Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL:Hai quan hệ n:1, nhưng không phải cả hai cùng một lúc

Thiết kế hiện tại của bạn được gọi là vòng cung độc quyền nơi sets bảng có hai khóa ngoại và cần chính xác một trong số chúng không phải là null. Đây là một cách để triển khai các liên kết đa hình, vì một khóa ngoại nhất định chỉ có thể tham chiếu đến một bảng đích.

Một giải pháp khác là tạo một "bảng xếp hạng cao" chung cho cả usersschools tham chiếu, và sau đó sử dụng nó làm cha của sets .

create table set_owner

create table users 
  PK is also FK --> set_owner

create table schools
  PK is also FK --> set_owner

create table sets 
  FK --> set_owner

Bạn có thể coi điều này tương tự như một giao diện trong mô hình OO:

interface SetOwner { ... }

class User implements SetOwner { ... }

class School implements SetOwner { ... }

class Set {
  SetOwner owner;
}

Re nhận xét của bạn:

Để bảng SetOwners tạo các giá trị id. Bạn phải chèn vào SetOwners trước khi có thể chèn vào Người dùng hoặc Trường học. Vì vậy, hãy đặt id trong Người dùng và Trường học không tự động tăng dần; chỉ sử dụng giá trị được tạo bởi SetOwners:

INSERT INTO SetOwners DEFAULT VALUES; -- generates an id
INSERT INTO Schools (id, name, location) VALUES (LAST_INSERT_ID(), 'name', 'location');

Bằng cách này, sẽ không có giá trị id đã cho nào được sử dụng cho cả trường học và người dùng.

Bạn chắc chắn có thể làm được điều này. Trên thực tế, có thể có các cột khác chung cho cả Người dùng và Trường học, và bạn có thể đặt các cột này trong SetOwners siêu bảng. Điều này nằm trong Kế thừa bảng lớp của Martin Fowler mẫu.

Bạn cần phải tham gia. Nếu bạn đang truy vấn từ một Tập hợp nhất định và bạn biết nó thuộc về người dùng (không phải trường học), bạn có thể bỏ qua việc tham gia SetOwners và tham gia trực tiếp với Người dùng. Tham gia không nhất thiết phải thực hiện bằng khóa ngoại.

SELECT u.name FROM Sets s JOIN Users u ON s.SetOwner_id = u.id WHERE ...

Nếu bạn không biết liệu một tập hợp nhất định thuộc về Người dùng hay Trường học, bạn phải thực hiện kết hợp bên ngoài với cả hai:

SELECT COALESCE(u.name, sc.name) AS name 
FROM Sets s 
LEFT OUTER JOIN Users u ON s.SetOwner_id = u.id
LEFT OUTER JOIN Schools sc ON s.SetOwner_id = sc.id 
WHERE ...

Bạn biết rằng SetOwner_id phải khớp với một hoặc bảng khác, Người dùng hoặc Trường học, nhưng không phải cả hai.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQLdb của Python không thể tìm thấy libmysqlclient.dylib với MySQL của Homebrewed

  2. Xây dựng hệ thống bản tin với PHP và MySQL

  3. Hàng Chẵn và Lẻ cho một bảng

  4. MySQL Errno 150

  5. Lỗi MySQL 5.7 (1093:Bạn không thể chỉ định bảng đích ___ cho bản cập nhật trong mệnh đề FROM) - giải pháp thông thường không hoạt động