对两列主键的外键引用

时间:2010-03-19 16:10:32

标签: sql schema primary-key

我正在构建一个必须在MySQL,PostgreSQL和SQLite上运行的数据库。我的一个表有一个两列主键:

CREATE TABLE tournament (
    state CHAR(2) NOT NULL, 
    year INT NOT NULL,
    etc..., 
    PRIMARY KEY(state, year)
);

我希望从另一个表中引用tournament表,但我希望此引用为 nullable 。这就是我如何做到这一点,想象一个胜利者不一定有锦标赛:

CREATE TABLE winner (
    name VARCHAR NOT NULL,
    state CHAR(2) NULL,
    year INT NULL
);

如果state为空但year不为,或反之亦然,则该表将不一致。我相信以下FOREIGN KEY约束修复了它:

ALTER TABLE winner ADD CONSTRAINT FOREIGN KEY fk (name, state) REFERENCES tournament (name, state);

这是实施一致性的正确方法吗?这个架构是否正确规范化了?

1 个答案:

答案 0 :(得分:4)

规则#1:总是说你正在使用的数据库

好的,我建议您查看ON DELETE子句和MATCH子句。因为,Pg非常符合SQL,我会指向CREATE TABLE上的当前文档。

摘录:

  

这些子句指定外键   约束,这需要一个   一组一列或多列   新表必须只包含值   匹配引用的值   某些行的列   参考表。如果refcolumn是   省略,主键   使用reftable。引用   列必须是a的列   中的唯一或主键约束   引用的表。注意   外键约束不可能   在临时表和。之间定义   永久表格。

     

插入引用的值   列与...匹配   引用表的值和   使用给定的引用列   比赛类型。有三场比赛   类型:MATCH FULL,MATCH PARTIAL,和   MATCH SIMPLE,也是   默认。 MATCH FULL不允许一个   多列外键的列   除非所有外键列都为null   是空的。 MATCH SIMPLE允许一些   外键列为null时   外键的其他部分都没有   空值。 MATCH PARTIAL还没有   实现。

     

另外,当数据在   引用的列已更改,确定   对数据执行操作   这张表的专栏。 ON DELETE   子句指定要执行的操作   当一个被引用的行   引用的表正在删除。   同样,ON UPDATE子句   指定a时要执行的操作   引用的引用列   表正在更新为新值。   如果行更新了,但是   引用列实际上并不是   改变了,没有采取任何行动。   除NO之外的参考行动   即使是行动检查也不能推迟   如果声明了约束   缓征。有以下几点   每个条款可能采取的行动:

此外,MS SQL存在一个主要的例外 - 它不允许外键中的部分匹配(MATCH SIMPLE和MATCH PARTIAL)行为(默认值并强制执行MATCH FULL)。有一些解决方法,您可以在表的一部分上创建一个MATCH FULL索引,该索引对于任何复合键的组成部分都不是NULL。