复合主键中只有一个键作为外键
Only one key from composite primary key as foreign key
在此数据库中,key1
和 key2
组成了 table4
的复合主键,但我可以向 table3
添加外键仅包含 key1
.
为什么 MySQL 允许这样做?上面的数据库设计是不是一点意义都没有?
外键完全不依赖于主键。事实上,它们与主键无关。
主键的唯一用途是唯一标识一行。
外键的目的是确保对于引用 table(子 table)中的每个条目,在引用的 table(父 table)中必须有一个条目table)。 MySQL只是技术要求,被引用的列必须有索引(不一定是主键或唯一键,简单的索引就可以)。
因此,您的设计很有意义,是的。
此答案采用问题的 "add a foreign key to table3
" 表示在 table3
中添加了 FK(外键),引用 [=12= 的复合 PK(主键)的列之一].在标准 SQL 中,FK 可以引用 PK 的 proper/smaller 子集。
大概采用 "add a foreign key to table3
" 表示在 table4
中添加了 FK,其中 PK 的列之一引用 table3
。 table 中设置的 FK 列独立于其中的任何 PK 或 UNIQUE 声明。
在标准 SQL 中,FK 可以引用 PK 的 proper/smaller 子集。
引用的列列表必须声明为 PRIMARY KEY 或 UNIQUE。 (PRIMARY KEY 创建一个 UNIQUE NOT NULL 约束。)(约束必须是显式的,即使任何包含 UNIQUE 集合的 NOT NULL 列集合必须是唯一的。)
不幸的是,MySQL 允许您声明 FK 引用非唯一的列列表。即使这样的 FK 或一个引用非 NULL 列(在标准 SQL 中可以)没有正确实现,并且文档本身建议不要这样做:
The handling of foreign key references to non-unique keys or keys that contain NULL values is not well defined for operations such as UPDATE or DELETE CASCADE. You are advised to use foreign keys that reference only keys that are both UNIQUE (or PRIMARY) and NOT NULL.
(您可以思考什么是明确定义的操作,什么不是明确定义的操作,因为文档实际上并没有阐明。)
1.8.2.3 Foreign Key Differences
13.1.18 CREATE TABLE Syntax
13.1.18.6 Using FOREIGN KEY Constraints
PS 关系与 SQL
在关系模型中,FK 引用 CK(候选键)。超级键是唯一的列集。 CK 是一个不包含更小超级密钥的超级密钥。一个CK可以称为PK(primary key)。当列集的值必须出现在别处时,我们说存在 IND(包含依赖性)。 FK 是 IND 到 CK。当 IND 指向超级键时,我们可以称其为 "foreign superkey".
SQL PK
或 UNIQUE NOT NULL
声明了一个超级密钥。当它不包含声明为 SQL PK
或 UNIQUE NOT NULL
的较小列集时,它是一个 CK。 SQL FK
声明了一个外部超级密钥。因此,SQL PK 实际上可能 是 关系 PK(因此是 CK),而 UNIQUE NOT NULL 实际上可能 是 CK。 SQL FK 到其中之一实际上 是 关系 FK。
在此数据库中,key1
和 key2
组成了 table4
的复合主键,但我可以向 table3
添加外键仅包含 key1
.
为什么 MySQL 允许这样做?上面的数据库设计是不是一点意义都没有?
外键完全不依赖于主键。事实上,它们与主键无关。
主键的唯一用途是唯一标识一行。
外键的目的是确保对于引用 table(子 table)中的每个条目,在引用的 table(父 table)中必须有一个条目table)。 MySQL只是技术要求,被引用的列必须有索引(不一定是主键或唯一键,简单的索引就可以)。
因此,您的设计很有意义,是的。
此答案采用问题的 "add a foreign key to table3
" 表示在 table3
中添加了 FK(外键),引用 [=12= 的复合 PK(主键)的列之一].在标准 SQL 中,FK 可以引用 PK 的 proper/smaller 子集。
table3
" 表示在 table4
中添加了 FK,其中 PK 的列之一引用 table3
。 table 中设置的 FK 列独立于其中的任何 PK 或 UNIQUE 声明。
在标准 SQL 中,FK 可以引用 PK 的 proper/smaller 子集。
引用的列列表必须声明为 PRIMARY KEY 或 UNIQUE。 (PRIMARY KEY 创建一个 UNIQUE NOT NULL 约束。)(约束必须是显式的,即使任何包含 UNIQUE 集合的 NOT NULL 列集合必须是唯一的。)
不幸的是,MySQL 允许您声明 FK 引用非唯一的列列表。即使这样的 FK 或一个引用非 NULL 列(在标准 SQL 中可以)没有正确实现,并且文档本身建议不要这样做:
The handling of foreign key references to non-unique keys or keys that contain NULL values is not well defined for operations such as UPDATE or DELETE CASCADE. You are advised to use foreign keys that reference only keys that are both UNIQUE (or PRIMARY) and NOT NULL.
(您可以思考什么是明确定义的操作,什么不是明确定义的操作,因为文档实际上并没有阐明。)
1.8.2.3 Foreign Key Differences
13.1.18 CREATE TABLE Syntax
13.1.18.6 Using FOREIGN KEY Constraints
PS 关系与 SQL
在关系模型中,FK 引用 CK(候选键)。超级键是唯一的列集。 CK 是一个不包含更小超级密钥的超级密钥。一个CK可以称为PK(primary key)。当列集的值必须出现在别处时,我们说存在 IND(包含依赖性)。 FK 是 IND 到 CK。当 IND 指向超级键时,我们可以称其为 "foreign superkey".
SQL PK
或 UNIQUE NOT NULL
声明了一个超级密钥。当它不包含声明为 SQL PK
或 UNIQUE NOT NULL
的较小列集时,它是一个 CK。 SQL FK
声明了一个外部超级密钥。因此,SQL PK 实际上可能 是 关系 PK(因此是 CK),而 UNIQUE NOT NULL 实际上可能 是 CK。 SQL FK 到其中之一实际上 是 关系 FK。