SQL 中的 table 是否可以有多个列作为仅引用另一个 table 的一个主键的外键?

Can a table in SQL have multiple columns as foreign keys that refer only to one primary key of another table?

例如,table 公司有列 company_name、first_contact、second_contact 和 table 联系人有列 id(PK)、姓名、phone。 SQL 中的 table(公司)是否可以有多个列作为外键,仅引用另一个 table(联系人)的一个主键?

好的!从公司到联系人,您基本上有几个 one-to-one 关系。

查询数据时,您必须多次加入 Contacts table(每列一次是外键)

select *
from Companies c
join Contacts contact1 on c.first_contact=contact1.id
join Contacts contact2 on c.second_contact=contact2.id

是的,这是一个例子:

mysql> CREATE TABLE Contacts (id INT PRIMARY KEY);
Query OK, 0 rows affected (0.03 sec)

mysql> CREATE TABLE Companies (id INT PRIMARY KEY, company_name TEXT,
    -> first_contact INT, second_contact INT,
    -> FOREIGN KEY (first_contact) REFERENCES Contacts(id),
    -> FOREIGN KEY (second_contact) REFERENCES Contacts(id)
    -> );
Query OK, 0 rows affected (0.03 sec)

但以另一种方式设计数据库会更常见,用第三个 table 代替 Companies 中的两个外键:

mysql> CREATE TABLE CompanyContacts (
    -> contact_id INT NOT NULL,
    -> company_id INT NOT NULL,
    -> is_primary BOOL NOT NULL,
    -> PRIMARY KEY (contact_id, company_id),
    -> FOREIGN KEY (contact_id) REFERENCES Contacts(id),
    -> FOREIGN KEY (company_id) REFERENCES Companies(id)
    -> );
Query OK, 0 rows affected (0.04 sec)

一些优点:

  • 每个公司不限于两个联系人。
  • 您可以更简单地搜索联系人 — 您只需在 CompanyContacts.contact_id 中搜索联系人,而不是搜索联系人是否出现在 first_contact 或 second_contact 中。使用索引优化该查询更容易。

一些缺点:

  • 无法约束至少一个联系人是强制性的。您可以通过在设计中将 first_contact 声明为 NOT NULL 来实现此目的,但没有 SQL 约束要求每个公司在第三个 table 中存在一行。
  • 如果您对 JOIN 查询感到厌烦,这可能没有吸引力。但我建议您在拥有 many-to-many 关系时通过 JOIN 感到舒适table。