2011-01-12 153 views
1

複合外鍵索引不工作,因爲我認爲它會。 在以下示例中,我只希望在子表中允許使用10個組合。但即使父表中沒有匹配的組合,最後的插入語句也會成功。 有沒有其他方法可以實現這種約束?複合外鍵約束

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'); 

回答

1

按照documentation

在SQL標準控制如何進行比較來 主鍵時在 複合物(多重柱)的外鍵NULL值處理的MATCH子句。 InnoDB實質上實現了 MATCH SIMPLE定義的語義,允許外鍵全部或部分爲NULL。 在這種情況下,包含這種外鍵的(子表)行允許插入 ,並且與引用的 (父)表中的任何行都不匹配。使用 觸發器可以實現其他語義。

0

由於child.name字段聲明爲可爲空,它可以包含空值。它並沒有違反外鍵的概念。 解決方法是將fk字段作爲NOT NULL刪除

5

不要在外鍵列中使用空值;這種方式導致了黑暗的一面。你應該聲明這樣的列NOT NULL