SQL中的表能否将多列作为仅引用另一表的一个主键的外键?

时间:2019-05-08 16:14:18

标签: mysql sql foreign-keys relational-database

例如,表“公司”具有“ company_name”,“ first_contact”,“ second_contact”列,而表“联系人”具有id(PK),名称,电话列。 SQL中的表(公司)是否可以具有多列作为仅引用另一表(联系人)的一个主键的外键?

2 个答案:

答案 0 :(得分:2)

是的,这里有一个例子:

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)

但是用另一种方法设计数据库会更常见,用第三张表而不是公司中的两个外键:

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)

一些优点:

  • 每个公司不限于两个联系人。
  • 您可以更简单地搜索联系人-而不是搜索联系人是first_contact还是second_contact,您只需在CompanyContacts.contact_id中进行搜索即可。使用索引优化查询更为容易。

一些缺点:

  • 没有办法限制至少一个联系人为必需。您可以通过在设计中将first_contact声明为NOT NULL来实现此目的,但是没有SQL约束要求每个公司的第三张表中都必须存在一行。
  • 如果您因JOIN查询而推迟,这可能不会很有吸引力。但是,我建议您在拥有多对多关系时熟悉进行JOIN。

答案 1 :(得分:0)

当然!从公司到联系人,您实际上具有几种一对一的关系。

查询数据时,您必须多次加入“联系人”表(每列一次为外键)

@Component({
  selector: 'main',
  template: '<div><a routerLink="/another">anotherComponent</a></div>',
  styles: [`div {
      position: fixed;
      min-width: 100%;
      background-image: url("https://source.unsplash.com/1920x1080?stars") !important;
      background-repeat: no-repeat;
      background-size: 100%;
    background-position: center;
      background-size: cover;
}`]
})

  @Component({
    selector: 'another',
    template: '<div><a routerLink="/">main</a></div>',
    styles: [`div {
      position: fixed;
      min-width: 100%;
      background-image: url("https://source.unsplash.com/1920x1080?landscape") !important;
      background-repeat: no-repeat;
      background-size: 100%;
      background-position: center;
      background-size: cover;
      }`]
  })