Schema: 不必要的代理键
适用于 ✅ 开源版 ✅ 专业版 ✅ 企业版
代理键与自然键的讨论几乎与 SQL 本身一样古老。两种方法都有其优点和缺点,具体取决于您正在设计的表的性质。简而言之
- 代理键(例如
IDENTITY
或UUID
)没有业务价值,因此可以在任何数据上生成,包括未正确规范化的数据。 - 自然键是其所代表数据的真实占位符(例如 ISO 国家代码),这可以帮助防止连接来查找有用的信息,因为有用的信息已在外键中引用。
虽然关于模式是否应该统一设计以保持一致性(通常都支持代理键),或者是否可以在几个表上有一些例外,存在很多争论,但有一个例外,即代理键通常是错误的选择:关系表!在像这样的关系表中
CREATE TABLE actor ( actor_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, first_name TEXT NOT NULL, last_name TEXT NOT NULL ); CREATE TABLE film ( film_id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, title TEXT NOT NULL ); CREATE TABLE film_actor ( actor_id BIGINT NOT NULL REFERENCES actor, film_id BIGINT NOT NULL REFERENCES film, PRIMARY KEY (actor_id, film_id) );
模式设计者可能很想在 FILM_ACTOR
表中添加一个 FILM_ACTOR_ID
,但为什么呢?永远不需要仅通过代理键来引用多对多关系条目。我们总是使用外键,如果模式已正确规范化,外键至少应该有一个 UNIQUE
约束。为什么不将其设为 PRIMARY KEY
?
这篇博文从性能的角度讨论了关系表中无用代理键的成本这一主题。
反馈
您对此页面有任何反馈吗? 我们很乐意听到!