是否可以将表的外键作为另一个表的复合主键的一部分? 例如,如果我有两个表,一个包含有关不同用户的所有活动项目的信息,另一个包含有关项目正在使用的设备的信息:
项目表:
Composite Primary Keys: UserId, ProjectId
(两者都不是独一无二的)
设备表:
Composite Primary Keys: UserId, ProjectId, EquipmentId
(两者都不是独一无二的)
现在可以将设备表中的ProjectId设置为项目表中的外键吗?当我尝试时,我得到一个错误,说项目表中的列与现有的主键或唯一约束不匹配?
答案 0 :(得分:9)
没有
创建外键时,另一个表中“指向”的键必须是UNIQUE或PRIMARY KEY约束。您无法建立指向允许重复值的列的外键。如果你更新另一个表中的一个重复值(例如),那么很难想象数据应该如何“行动”。(/ p>
要执行您想要的操作,您必须建立一个Projects表,其中ProjectID是UNIQUE或PRIMARY KEY,然后将中的外键其他表中的外键指向该表。
顺便说一句,您使用术语“主键”来描述构成主键的每个表中的列。实际上,每个表可以只有一个主键。该密钥可以由一个或多个列组成,但密钥本身仍然被称为单数。使用主键优化搜索时,这是一个重要的区别。
答案 1 :(得分:0)
它不知道这是否是一个好的设计实践,但可以肯定的是,有一个表的复合外键是其他表的复合主键的一部分。
假设我们有一个表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)的组合是唯一的,则无关紧要。
答案 2 :(得分:-3)