复合外键约束

时间:2011-01-12 09:16:33

标签: mysql

复合外键索引不能像我想象的那样工作。 在以下示例中,我只想在子表中允许10种组合。但即使父表中没有匹配的组合,最后一个insert语句也是成功的。 有没有其他方法可以实现这种约束?

drop table if exists child;
drop table if exists parent;

CREATE TABLE parent(
`ID` int(11) default NULL,
`name` varchar(100) default NULL,
`city` varchar(100) default NULL,
key (name,city),
key (ID)
) ENGINE=InnoDB;

create table child(
userID int not null,
`name` varchar(100) default NULL,
`city` varchar(100) default NULL,
key (name,city),
FOREIGN KEY (name,city) REFERENCES parent(name,city),
primary key (userID)
) ENGINE=InnoDB;

insert into parent values (1, 'Amar', 'mumbai');
insert into parent values (2, 'Amar', 'Delhi');
insert into parent values (3, 'Amar', NULL);
insert into parent values (4, 'Akbar', 'mumbai');
insert into parent values (5, 'Akbar', 'Delhi');
insert into parent values (6, 'Akbar', NULL);
insert into parent values (7, 'Anthony', 'mumbai');
insert into parent values (8, 'Anthony', 'Delhi');
insert into parent values (9, 'Anthony', NULL);
insert into parent values (10, NULL, NULL);

insert into child values (2, NULL, 'mumbai');

3 个答案:

答案 0 :(得分:5)

不要在外键列中使用空值;那种方式导致了黑暗的一面。您应该声明此类列NOT NULL

答案 1 :(得分:1)

根据documentation

  

SQL标准中的MATCH子句控制a中NULL值的方式   复合(多列)外键在比较时处理   主键。 InnoDB基本上实现了定义的语义   MATCH SIMPLE,允许外键全部或部分为NULL。   在这种情况下,包含这样的外键的(子表)行是   允许插入,并且与引用的任何行都不匹配   (父)表。可以使用实现其他语义   触发器。

答案 2 :(得分:0)

因为child.name字段声明为nullable,所以它可以包含空值。它不违反外键概念。 解决方案是将fk字段decalre为NOT NULL