sql >> Databáze >  >> RDS >> Mysql

MySQL:Dva vztahy n:1, ale ne oba najednou

Váš aktuální návrh se nazývá exkluzivní oblouky kde sets tabulka má dva cizí klíče a potřebuje, aby právě jeden z nich nebyl nulový. Toto je jeden způsob, jak implementovat polymorfní asociace, protože daný cizí klíč může odkazovat pouze na jednu cílovou tabulku.

Dalším řešením je vytvořit společnou "supertable", kterou oba users a schools odkazy a poté je použijte jako rodiče 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

Můžete si to představit jako analogii k rozhraní v modelování OO:

interface SetOwner { ... }

class User implements SetOwner { ... }

class School implements SetOwner { ... }

class Set {
  SetOwner owner;
}

K vašim komentářům:

Nechte tabulku SetOwners vygenerovat hodnoty id. Musíte vložit do SetOwners, než budete moci vložit buď do Users nebo Schools. Takže nastavte ID v Users and Schools ne automatické zvyšování; stačí použít hodnotu, která byla vygenerována SetOwners:

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

Tímto způsobem nebude použita žádná daná hodnota id jak pro školu, tak pro uživatele.

Určitě to dokážeš. Ve skutečnosti mohou existovat další sloupce, které jsou společné pro uživatele i školy, a tyto sloupce byste mohli umístit do supertabulky SetOwners. To se dostane do dědičnosti tabulky tříd Martina Fowlera vzor.

Musíte se připojit. Pokud se dotazujete z dané sady a víte, že patří uživateli (ne škole), můžete přeskočit připojení k SetOwners a připojit se přímo k uživatelům. Spojení nemusí nutně probíhat pomocí cizích klíčů.

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

Pokud nevíte, zda daná sada patří uživateli nebo škole, budete muset provést vnější spojení k oběma:

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

Víte, že SetOwner_id musí odpovídat jedné nebo druhé tabulce, Users nebo Schools, ale ne oběma.



  1. Přesouvání webu Wordpress do Dockeru:Chyba při navazování připojení k databázi

  2. Aplikace pro Android pro odesílání obrázku do MySQL

  3. Některé skvělé zprávy pro zákazníky Standard Edition v SQL Server 2014

  4. Chyba Sloupec dotazu SQL neexistuje