Mysql
 sql >> Baza danych >  >> RDS >> Mysql

MySQL:Dwie relacje n:1, ale nie obie jednocześnie

Twój obecny projekt nazywa się ekskluzywnymi łukami gdzie sets table ma dwa klucze obce i dokładnie jeden z nich musi mieć wartość inną niż null. Jest to jeden ze sposobów implementacji asocjacji polimorficznych, ponieważ dany klucz obcy może odwoływać się tylko do jednej tabeli docelowej.

Innym rozwiązaniem jest stworzenie wspólnego „supertable”, aby obaj users i schools referencje, a następnie użyj go jako rodzica 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

Można to potraktować jako analogiczne do interfejsu w modelowaniu OO:

interface SetOwner { ... }

class User implements SetOwner { ... }

class School implements SetOwner { ... }

class Set {
  SetOwner owner;
}

Przypomnij swoje komentarze:

Niech tabela SetOwners generuje wartości id. Musisz wstawić do SetOwners, zanim będziesz mógł wstawić do Użytkowników lub Szkół. Dlatego nie umieszczaj identyfikatora w Użytkownicy i Szkoły nie autoinkrementacja; po prostu użyj wartości wygenerowanej przez SetOwners:

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

W ten sposób żadna podana wartość identyfikatora nie będzie używana zarówno dla szkoły, jak i użytkownika.

Z pewnością możesz to zrobić. W rzeczywistości mogą istnieć inne kolumny, które są wspólne zarówno dla użytkowników, jak i szkół, i można je umieścić w supertabeli SetOwners. To trafia do Dziedziczenia tabeli klas Martina Fowlera wzór.

Musisz dołączyć. Jeśli wysyłasz zapytania z danego Zestawu i wiesz, że należy on do użytkownika (nie do szkoły), możesz pominąć dołączanie do SetOwners i dołączyć bezpośrednio do Użytkowników. Połączenia niekoniecznie muszą odbywać się za pomocą kluczy obcych.

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

Jeśli nie wiesz, czy dany zestaw należy do Użytkownika, czy do Szkoły, musisz wykonać zewnętrzne połączenie do obu:

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 ...

Wiesz, że SetOwner_id musi pasować do jednej lub drugiej tabeli, Użytkownicy lub Szkoły, ale nie do obu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySql:Policz, ile razy słowa występują w kolumnie

  2. Formularz PHP/HTML nie aktualizuje MySQL

  3. Dlaczego MySQL nie zawsze używa tutaj funkcji łączenia indeksów?

  4. upewnij się, że wynik metody pobierania PDO jest błędem lub pustym wynikiem

  5. Czy można użyć klauzuli WHERE do zaznaczenia wszystkich rekordów w instrukcji SQL?