10

我最近遇到了 MySQL 本身和 MySQL 中的 Composite Primary Keys 的主题,特别是它如何有用以及它的优缺点是什么

我想玩这个,所以我以这种方式创建了三个表:

CREATE TABLE person(
    personId INT(11) NOT NULL,
    personName VARCHAR(20) NOT NULL,
    PRIMARY KEY(personId)
)

CREATE TABLE language(
    languageId INT(11) NOT NULL,
    languageName VARCHAR(20) NOT NULL,
    PRIMARY KEY(personId)
)

CREATE TABLE personLanguage(
    personId INT(11) NOT NULL,
    languageId INT(11) NOT NULL,
    description VARCHAR(20) NOT NULL,
    PRIMARY KEY(personId, languageId),
    FOREIGN KEY (personId) REFERENCES person(personId) ON UPDATE CASCADE ON DELETE CASCADE,
    FOREIGN KEY (languageId) REFERENCES language(languageId) ON UPDATE CASCADE ON DELETE CASCADE
)

我可以直接将数据插入到人员和语言表中,我的问题是:

  1. 对于 personLanguage 表,我是否只需要插入描述列,而其他列是自动引用的,还是我还需要在 personLanguage 表中插入其他两列的值

  2. 是否有可能在插入其他两个表中的数据后立即自动更新 personLanguage 表中的 personId 和 languageId personLanguage 表中的两列

  3. 如何获取三个表相关的数据,例如我需要知道 personId=1 的人说哪种语言?它也是使用连接的直接查询还是有其他方法可以做,因为我使用复合主键

很多问题困扰着我,我真的找不到一个完整的工作示例来检查使用复合主键的确切利弊。如果有人可以使用我的示例详细说明这一点,那将非常有帮助。

我知道我已经问了一些基本的,一些毫无意义的问题,但请耐心等待我并就这个话题提出一些好的看法

4

2 回答 2

3

对于 personLanguage 表,我是否只需要插入描述列,而其他列是自动引用的,还是我还需要在 personLanguage 表中插入其他两列的值

是的,您需要插入所有三列才能完全有效。否则数据库将不知道您尝试将此记录绑定到什么人或语言。

是否有可能在插入其他两个表中的数据后立即自动更新 personLanguage 表中的 personId 和 languageId personLanguage 表中的两列

您可以通过插入触发器来执行此操作,但这可能没有任何意义。所以,假设您刚刚输入了一种新语言——比如法语。您根本不需要在 personLanguage 表中输入任何值,因为您的现有用户可能不希望获得法语信息。同样的情况也适用于创建一个新人。你可能有很多种语言。大多数人不会说大多数语言,所以同样,您不希望将记录自动输入到 personLanguage 表中。

至于更新个人和语言的记录,KEYS 不应该改变。这就是为什么你会做这样的事情。一旦 Bob 或 Alice 被分配了一个 personId,他们就是那个 Id。一旦为法语分配了一个langaugeId,它就应该始终是那个languageId。

如何获取三个表相关的数据,例如我需要知道 personId=1 的人说哪种语言?它也是使用连接的直接查询还是有其他方法可以做,因为我使用复合主键

嗯,这是个棘手的问题。如果您尝试获取 personId=1 使用的所有语言,则加入非常简单。

select pl.personId, l.languageId, l.languageName 
  from personLanguage pl
    join language l on l.languageId = pl.languageId
    where pl.personId = 1

如果您试图弄清楚您应该与该人交流哪种语言,情况会变得更加复杂,因为该人可能没有定义任何 personLanguages。如果您可以接受空值,则可以使用外连接,但您需要定义查询以便只返回一种语言。

于 2012-09-20T14:39:35.963 回答
2
  1. 对于 personLanguage 表,我是否只需要插入描述列,而其他列是自动引用的,还是我还需要在 personLanguage 表中插入其他两列的值

    personLanguage如果引用的表中存在现有键,则只能将值插入。person这意味着您必须language在将值插入personLanguage. 但是,如果您有一个NULLable 字段,您可以这样做,但它会违反唯一复合键。

  2. 是否有可能在插入其他两个表中的数据后立即自动更新 personLanguage 表中的 personId 和 languageId personLanguage 表中的两列

    您指定的约束 ( ON UPDATE CASCADE) 意味着当任何一个中的引用值发生更改时,personlanguage会自动更新personLanguage. 但是,不能违反对 的PRIMARY KEY约束personLanguage

  3. 如何获取三个表相关的数据,例如我需要知道 personId=1 的人说哪种语言?它也是使用连接的直接查询还是有其他方法可以做,因为我使用复合主键

    由于这是一个基本示例,因此实际上不需要这样做。在扩展形式中,您可以使用显式JOINs 在表之间获取数据。

再多想几句...

复合键通常用于元组(或集合)中的引用。这意味着当您有一个组合键 ( col1, col2) on 时table1,这将引用一个组合键 ( col1, col2) on table2

于 2012-09-20T14:35:09.227 回答