2017-03-04 115 views
1

我有以下父表:复合外键

create table A(
    a int(64) unsigned not null, 
    b set('a', 'b', 'c') not null default '', 
    c set('d', 'e') not null default '', 
    primary key (a,b,c) 
) 

而且孩子:

create table B(
    d int(64) unsigned not null auto_increment, 
    a int(64) unsigned not null, 
    c set('d', 'e') not null default '', 
    primary key (d), 
    key fk1 (a,c), 
    constraint fk1 foreign key (a, c) references (a, c) 
) 

但后来我得到一个FK错误上创建mysql日志中的子表:

表的外键约束出错外键(a,c)引用 A(a,c):无法找到引用表中 引用列显示为第一列的索引,或 表中的列类型与被引用表的约束不匹配。

我的SQL有什么不正确?

+0

围绕列名称有单引号。我认为这是一个错字,并投票结束这些问题。 –

+0

@GordonLinoff不,我不认为这是一个错字。 Ty用于格式化 – user1561108

+0

1.引用的表名缺失。 2.所引用的表格上没有可以支持FK的索引。 3.在相同的列上引用没有唯一索引的列(对于引用的表)是一种奇怪的设计。 –

回答

2

定义外键时,MySQL要求远程表中的列存在索引,以便它可以高效地执行约束检查。

它可以是一个完全引用的列上的索引,或者是一个以被引用的列开始并包含其他列的索引,所以在你的情况下,表A应该有一个带有列(a,c)一些其他人。

现在,在表A中有一组列(a,b,c)的索引。 请注意,列的顺序很重要,(a,b,c)上的索引不会与(a,c,b)中的索引相同。

FK引用列(a,c)。这些列在表A中没有索引,或者是以这两个列开头并包含更多列的任何其他索引。

所以,你有两个选择:

  1. 修改PK表A是(A,C,B),而不是(A,B,C)。请注意, 在某些情况下,这可能会对您的 查询产生性能影响,因为其中一些查询可能无法使用索引。
  2. 在甲添加一个附加的索引只是这两个列:

    ALTER TABLE A
    ADD INDEX tempindexac);

+0

即使解决方案是在错误日志中,它会让我永远解决它。谢谢@YossiVainshtein – user1561108