对两列主键的外键引用

Ada*_*nst 5 sql schema primary-key

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

CREATE TABLE tournament (
    state CHAR(2) NOT NULL, 
    year INT NOT NULL,
    etc..., 
    PRIMARY KEY(state, year)
);
Run Code Online (Sandbox Code Playgroud)

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

CREATE TABLE winner (
    name VARCHAR NOT NULL,
    state CHAR(2) NULL,
    year INT NULL
);
Run Code Online (Sandbox Code Playgroud)

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

ALTER TABLE winner ADD CONSTRAINT FOREIGN KEY fk (name, state) REFERENCES tournament (name, state);
Run Code Online (Sandbox Code Playgroud)

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

Eva*_*oll 4

规则#1:始终说出您正在使用的数据库

好的,我建议你看看这个ON DELETE条款,再看看这个MATCH条款。因为,Pg 相当符合 SQL,我将向您指出CREATE TABLE.

摘抄:

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

插入到引用列中的值将使用给定的匹配类型与引用表和引用列的值进行匹配。共有三种匹配类型:MATCH FULL、MATCH PARTIAL 和 MATCH SIMPLE,这也是默认的。MATCH FULL 不允许多列外键的一列为空,除非所有外键列都为空。MATCH SIMPLE 允许某些外键列为空,而外键的其他部分不为空。MATCH PARTIAL 尚未实现。

此外,当引用的列中的数据发生更改时,会对该表的列中的数据执行某些操作。ON DELETE 子句指定删除引用表中的引用行时要执行的操作。同样,ON UPDATE 子句指定当引用表中的引用列更新为新值时要执行的操作。如果行已更新,但引用的列实际上并未更改,则不执行任何操作。即使约束被声明为可延迟,除 NO ACTION 检查之外的引用操作也无法延迟。每个子句有以下可能的操作:

另外,MS SQL 存在一个主要例外——它不允许外键中的部分匹配(MATCH SIMPLE 和 MATCH PARTIAL)行为(默认并强制 MATCH FULL)。有一些解决方法,可以在表的任何组合键成分的 IS NOT NULL 部分上创建 MATCH FULL 索引。