可用版本:Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

Schema: 不必要的代理键

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

代理键与自然键的讨论几乎与 SQL 本身一样古老。两种方法都有其优点和缺点,具体取决于您正在设计的表的性质。简而言之

  • 代理键(例如 IDENTITYUUID)没有业务价值,因此可以在任何数据上生成,包括未正确规范化的数据。
  • 自然键是其所代表数据的真实占位符(例如 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

这篇博文从性能的角度讨论了关系表中无用代理键的成本这一主题。

反馈

您对此页面有任何反馈吗? 我们很乐意听到!

The jOOQ Logo