9

是否可以让一个表的外键成为另一个表的复合主键的一部分?例如,如果我有两张表,一张包含有关不同用户的所有活动项目的信息,另一张包含有关项目正在使用哪些设备的信息:

项目表:

Composite Primary Keys: UserId, ProjectId(两者都不是独一无二的)

设备表:

Composite Primary Keys: UserId, ProjectId, EquipmentId (两者都不是独一无二的)

现在是否可以将设备表中的 ProjectId 设置为项目表中的外键?当我尝试时,我收到一条错误消息,指出项目表中的列与现有的主键或唯一约束不匹配?

4

3 回答 3

14

不。

当您创建外键时,您在另一个表中“指向”的键必须是 UNIQUE 或 PRIMARY KEY 约束。您不能建立指向允许重复值的列的外键。如果您更新另一个表中的一个重复值(例如),那么很难想象数据应该如何“起作用”。

要执行您想要的操作,您必须建立一个 ProjectID 为 UNIQUE 或 PRIMARY KEY 的 Projects 表,然后将其他两个表中的外键指向该表。

顺便说一句,您使用术语“主键”来描述每个表中构成主键的列。实际上,每个表可以有一个且只有一个主键。该键可以由一列或多列组成,但键本身仍以单数形式引用。这是使用主键优化搜索时的一个重要区别。

于 2012-10-01T19:06:53.557 回答
-1

它不知道这是否是一个好的设计实践,但可以肯定的是,一个表的复合外键是另一个表的复合主键的一部分。

假设我们有一个表 test1 有一个复合主键 (A, B)

现在我们可以有一个表说 test2 具有主键 (P, Q, R),其中 test2 的 (P,Q) 引用 test2 的 (A,B)。

我在 MySql 数据库中运行了以下脚本,它工作得很好。

CREATE TABLE `test1` (
`A` INT NOT NULL,
`B` VARCHAR(2) NOT NULL,
`C` DATETIME NULL,
`D` VARCHAR(45) NULL,
PRIMARY KEY (`A`, `B`));


CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NOT NULL,
`R` INT NOT NULL,
`S` DATETIME NULL,
`T` VARCHAR(8) NULL,
PRIMARY KEY (`P`, `Q`, `R`),
INDEX `PQ_idx` (`P`,`Q` ASC),
CONSTRAINT `PQ`
  FOREIGN KEY (`P`, `Q`)
  REFERENCES `test1` (`A`,`B`)
  ON DELETE CASCADE
  ON UPDATE CASCADE);

在上述情况下,数据库期望 (A,B) 的组合是唯一的,并且它是 test1 表中的主键。


但是,如果您尝试执行以下操作,脚本将会失败。数据库不允许您创建 test2 表。

CREATE TABLE `test2` (
`P` INT NOT NULL,
`Q` VARCHAR(2) NULL,
`R` DATETIME NULL,
`S` VARCHAR(8) NULL,
`T` VARCHAR(45) NULL,
  INDEX `P_idx` (`P` ASC),
  INDEX `Q_idx` (`Q` ASC),
  CONSTRAINT `P`
    FOREIGN KEY (`P`)
    REFERENCES `test1` (`A`)
    ON DELETE CASCADE
    ON UPDATE CASCADE,
  CONSTRAINT `Q`
    FOREIGN KEY (`Q`)
    REFERENCES `test1` (`B`)
    ON DELETE CASCADE
    ON UPDATE CASCADE);

在上述情况下,数据库期望 A 列单独唯一,B 列也是如此。(A,B)的组合是否唯一无关紧要。

于 2017-02-21T20:14:20.530 回答
-2

@Larry Lustig 外键可以是另一个表中主键的一部分。

来源:依赖关系

检查表之间的关系:Zdarzenie(事件)和 TypZdarzenia(事件类型)

足球比赛 - 数据库

于 2015-08-18T10:48:25.637 回答