sql >> Database teknologi >  >> RDS >> Mysql

MySQL:To n:1 relationer, men ikke begge på én gang

Dit nuværende design kaldes eksklusive buer hvor sets tabellen har to fremmednøgler, og skal præcis én af dem være ikke-nul. Dette er en måde at implementere polymorfe associationer på, da en given fremmednøgle kun kan referere til én måltabel.

En anden løsning er at lave en fælles "supertable", som begge users og schools referencer, og brug det derefter som overordnet for 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

Du kan tænke på dette som analogt med en grænseflade i OO-modellering:

interface SetOwner { ... }

class User implements SetOwner { ... }

class School implements SetOwner { ... }

class Set {
  SetOwner owner;
}

Vedrørende dine kommentarer:

Lad SetOwners-tabellen generere id-værdier. Du skal indsætte i SetOwners, før du kan indsætte i enten Users eller Schools. Så gør id'erne i Brugere og Skoler ikke automatisk stigning; bare brug den værdi, der blev genereret af SetOwners:

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

På denne måde vil ingen given id-værdi blive brugt for både en skole og en bruger.

Du kan helt sikkert gøre dette. Faktisk kan der være andre kolonner, der er fælles for både brugere og skoler, og du kan placere disse kolonner i supertabellen SetOwners. Dette kommer ind i Martin Fowlers Klassebordsarv mønster.

Du skal deltage. Hvis du forespørger fra et givet sæt, og du ved, at det tilhører en bruger (ikke en skole), kan du springe over at deltage i SetOwners og slutte sig direkte til brugere. Joins behøver ikke nødvendigvis at ske med fremmednøgler.

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

Hvis du ikke ved, om et givet sæt tilhører en bruger eller en skole, skal du lave en ekstern joinforbindelse til begge:

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

Du ved, at SetOwner_id skal matche den ene eller den anden tabel, Brugere eller Skoler, men ikke begge.



  1. @ Symbol - en løsning til rekursiv SELECT-forespørgsel i Mysql?

  2. Bredt varchar-felt årsager Anmodet konvertering understøttes ikke fejl ved brug af openquery med MySQL-linket server

  3. Sammenkæd flere rækker i enkelte rækker i MySQL

  4. PHP MYSQL OPDATERING hvis Exist eller INSERT hvis ikke?