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。
例如,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。