2 Một bảng trong SQL có thể có nhiều cột làm khóa ngoại chỉ tham chiếu đến một khóa chính của bảng khác không?

câu hỏi được tạo ra tại Wed, May 8, 2019 12:00 AM
Ví dụ:

Công ty bảng có các cột company_name, first_contact, second_contact và các liên hệ bảng có các cột id (PK), tên, điện thoại. Một bảng (công ty) trong SQL có thể có nhiều cột làm khóa ngoại chỉ tham chiếu đến một khóa chính của một bảng khác (danh bạ) không?     

0
  1. Không có vấn đề gì với điều đó. Có lẽ ví dụ phổ biến nhất là bảng messages với from_user_idto_user_id cả hai đều tham khảo bảng users.
    2019-05-08 16: 19: 25Z
  2. CÓ và KHÔNG. Bạn có thể nhưng có thể phải vứt bỏ một số tính năng như xóa tầng.
    2019-05-08 16: 20: 15Z
  3. @ P.Salmon - Có vấn đề gì với ON DELETE CASCADE? Nó nên hoạt động IMHO.
    2019-05-08 16: 21: 26Z
  4. @ Paul Spiegel Nếu bạn có FK trên công ty và First_contact với xóa tầng trên cả hai và sau đó bạn đã xóa công ty trong danh bạ, mysql sẽ phản ứng thế nào? Tôi chưa thử, vì vậy tôi chỉ nghĩ lớn thôi.
    2019-05-08 16: 24: 29Z
  5. @ P.Salmon Khi bạn xóa một liên hệ, tất cả các công ty đang giới thiệu liên hệ đó trong first_contact hoặc second_contact sẽ bị xóa. Rằng bạn có thể không muốn điều đó - là một câu hỏi khác. Nhưng tôi không hiểu tại sao điều đó không hiệu quả.
    2019-05-08 16: 28: 50Z
2 Câu trả lời                              2                         

Có, đây là một ví dụ:

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)

Nhưng sẽ phổ biến hơn khi thiết kế cơ sở dữ liệu theo cách khác, với bảng thứ ba thay vì hai khóa ngoại trong Công ty:

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)

Một số lợi thế:

  • Bạn không bị giới hạn ở hai liên hệ trên mỗi công ty.
  • Bạn có thể tìm kiếm một liên hệ đơn giản hơn - thay vì tìm kiếm nếu một liên hệ xảy ra dưới dạng First_contact hoặc second_contact, bạn chỉ cần tìm kiếm nó trong CompanyLink.contact_id. Dễ dàng hơn để tối ưu hóa truy vấn đó bằng một chỉ mục.

Một số nhược điểm:

  • Không có cách nào để tạo một ràng buộc để thực hiện ít nhất một liên hệ bắt buộc. Bạn có thể làm điều này bằng cách khai báo First_contact là NOT NULL trong thiết kế của bạn, nhưng không có ràng buộc SQL nào yêu cầu một hàng tồn tại trong bảng thứ ba cho mỗi công ty.
  • Nếu bạn bị loại bỏ bởi các truy vấn THAM GIA, điều này có thể không hấp dẫn. Nhưng tôi khuyên bạn nên thoải mái khi thực hiện THAM GIA khi bạn có nhiều mối quan hệ nhiều-nhiều.
2
2019-05-08 17: 17: 13Z

Chắc chắn rồi! Về cơ bản, bạn có nhiều mối quan hệ một-một từ Công ty đến Danh bạ.

Khi truy vấn dữ liệu, bạn phải tham gia vào bảng Liên hệ nhiều lần (một lần trên mỗi cột là khóa ngoại)

select *
from Companies c
join Contacts contact1 on c.first_contact=contact1.id
join Contacts contact2 on c.second_contact=contact2.id
    
0
2019-05-08 16: 18: 39Z
nguồn đặt đây