【问题标题】:SQL: Is creating multiple foreign keys with one statement equivalent to creating them with one statement?SQL:用一个语句创建多个外键是否等同于用一个语句创建它们?
【发布时间】:2019-07-06 12:59:20
【问题描述】:

例如,让我们有以下表定义:

CREATE TABLE table1 
(
    id INT UNIQUE,
    name VARCHAR(100) UNIQUE,
    description VARCHAR(100),

    PRIMARY KEY (id, name)
);

现在我想创建另一个表,该表将具有上述复合主键的外键。以下两种说法是否等价?

1)

CREATE TABLE table2 
(
     id INT PRIMARY KEY,
     table1_id INT,
     table1_name VARCHAR(100),

     FOREIGN KEY (table1_id) REFERENCES table1(id),
     FOREIGN KEY (table1_name) REFERENCES table1(name)
);

2)

CREATE TABLE table2 
(
     id INT PRIMARY KEY,
     table1_id INT,
     table1_name VARCHAR(100),

     FOREIGN KEY (table1_id, table1_name) REFERENCES table1(id, name),
);

我注意到 Postgre SQL 在 1) 的情况下创建了两个 FK db 对象,在 2) 的情况下创建了一个 FK 对象。一切都会一样吗?

【问题讨论】:

  • (显然--)这是一个常见问题。在考虑发布之前,请始终在谷歌上搜索任何错误消息以及您的问题/问题/目标的许多清晰、简洁和准确的措辞,包括和不包括您的特定字符串/名称;阅读许多答案。如果您发布问题,请使用一个短语作为标题。请参阅How to Ask 和投票箭头鼠标悬停文本。 PS 这表明“没有显示任何研究工作”。

标签: sql postgresql foreign-keys one-to-many composite-primary-key


【解决方案1】:

一点也不。外键引用应该是主键。在这种情况下,您有一个复合主键(尽管可能不需要,见下文)。虽然允许外键引用唯一键(有些数据库甚至允许外键引用任何索引列),但这不是最佳做法。

当您使用复合主键(您的第二个示例)时,您保证id/name 在第一个表中对齐。当您使用单独的引用(您的第一个示例)时,您不知道它们是对齐的,因此id 可以引用table1 中的一行,而name 可以引用另一行。我怀疑那是你的意图。

无论如何,在表之间重复冗余数据是一种不好的做法。更好的数据模型是:

CREATE TABLE table1 (
  id INT PRIMARY KEY,
  name VARCHAR(100) UNIQUE,
  description VARCHAR(100),
);

CREATE TABLE table2 (
  id INT PRIMARY KEY,
  table1_id INT,
  FOREIGN KEY (table1_id) REFERENCES table1(id)
);

然后,如果您想要对应的name,请在第一个表中查找名称。

请注意,在 Postgres 中,我希望 INT 真的是 SERIAL,因此当您插入新行时,数据库会分配一个唯一的、递增的值。

如果您确实想要两个对 table1 的引用,那么使用两个 id 引用:

CREATE TABLE table2 (
  id INT PRIMARY KEY,
  table1_id INT,
  table1_id_2 INT,
  FOREIGN KEY (table1_id) REFERENCES table1(id),
  FOREIGN KEY (table1_id_2) REFERENCES table1(id)
);

【讨论】:

  • 我知道这可能不是将 id 和 name 作为复合主键的最佳示例,但我们假设是这种情况(在某些情况下,复合主键需要作为外键)。所以我的理解是,在这种情况下,我应该复合定义 FOREGIN KEY 语句,如示例 2)我给出的?
  • @Mr.Nicky 。 . .只需引用主键并在需要时查找其他值。这是使用数据库的最佳方式。在大多数数据库中,您只能引用唯一键或主键,因此如果一个键是唯一的并且您有一个复合主键,那么您的数据模型似乎不正确。
  • 我没有投反对票,但也许这被否决了,因为根据投反对票箭头鼠标悬停文本,它“没用”,因为它(您的另一个答案)只是给网站添加了混乱和推广通过回答一个显然很容易找到的无研究重复无用问题来解决未来的混乱。当然,网站所有者在重复他们的目标方面是自相矛盾的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多