在多个列上添加外键

10

我正在尝试在一个表的两列上创建一个外键,以指向另一个表的同一列,但似乎出现了错误...

这是我的做法:

CREATE TABLE test2 (
  ID INT NOT NULL AUTO_INCREMENT,  
  col1 INT NOT NULL,
  col2 INT NOT NULL, 
  PRIMARY KEY (ID),
  CONSTRAINT fk FOREIGN KEY (col1, col2)
                REFERENCES test1(ID, ID)
  ON UPDATE CASCADE
  ON DELETE RESTRICT
) ENGINE=InnoDB;

但是我得到了

错误1005(HY000):无法创建表'DB.test2'(errno:150)

然而,如果我只有一个列,则可以正确创建该表。

有人能指出这个错误在哪里吗?

谢谢


@Cybernate:抱歉,我忘记说明了,ID是test1表的主键,类型与col1和col2相同(INT)。该表还有许多其他列(但这不重要),没有设置其他约束或索引。 - nico
你尝试过不指定级联更新或删除吗? - Thomas
@Thomas:是的,我尝试省略ON UPDATE和ON DELETE,但结果并没有改变... - nico
2个回答

8
尝试在这里,但是得到了相同的错误。不过这个方法可以解决问题:
CREATE TABLE test2 (
  ID INT NOT NULL AUTO_INCREMENT,  
  col1 INT NOT NULL,
  col2 INT NOT NULL, 
  PRIMARY KEY (ID),
  CONSTRAINT fk FOREIGN KEY (col1)
                REFERENCES test1(ID)
  ON UPDATE CASCADE
  ON DELETE RESTRICT,
  CONSTRAINT fk2 FOREIGN KEY (col2)
                REFERENCES test1(ID)
  ON UPDATE CASCADE
  ON DELETE RESTRICT

) ENGINE=InnoDB

是的,我知道 - 你的脚本应该可以工作(即使它似乎没有太多意义)。然而,我猜这个新版本更好。


4
它能正常工作是因为您有两个独立的关系指向同一个父表列。可以这样理解,只有在父表键是多列键时,您才会使用原始帖子中的语法。如果父表列是单列,则对于每个要引用该父表列的子列,您必须创建一个单独的外键约束。 - Thomas
@Thomas:好的,现在我明白了!实际上,仔细想想,这很有道理。谢谢。 - nico

2
问题似乎在于您在同一个外键中两次指定了相同的父列(即(ID,ID))。以下内容应该可以解决问题:
Create Table Test1
    (
    PK1 int not null
    , PK2 int not null
    , Primary Key ( PK1, PK2 )
    )

Create Table Test2
    (
    Id int not null Auto_Increment
    , PK1 int not null
    , PK2 int not null
    , Primary Key ( ID )
    , Constraint FK_Test2
        Foreign Key ( PK1, PK2 )
        References Test1( PK1, PK2 )
    )

如果您想在一个子表中引用同一个父表列并希望有两列,那么您必须添加两个外键引用,如rsenna所示,因为它们代表两个独立的关系。

好的,但是我在Test1中没有复合主键... Test2中的两列应该指向Test1中相同的(唯一)主键。 - nico
@nico - 那么它们代表两个独立的关系,需要两个外键约束。只有当父列是多列键时,您才会使用您在原始帖子中的语法。 - Thomas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接