Mysql
 sql >> Datenbank >  >> RDS >> Mysql

MySQL:Zuordnungstabellen verstehen

Bei der Verwendung von Viele-zu-Viele-Beziehungen ist die einzige realistische Möglichkeit, dies zu handhaben, eine Zuordnungstabelle.

Nehmen wir an, wir haben eine Schule mit Lehrern und Schülern, ein Schüler kann mehrere Lehrer haben und umgekehrt.

Also machen wir 3 Tabellen

student
  id unsigned integer auto_increment primary key
  name varchar

teacher
  id unsigned integer auto_increment primary key
  name varchar

link_st
  student_id integer not null
  teacher_id integer not null
  primary key (student_id, teacher_id)

Die Schülertabelle wird 1000 Datensätze enthalten
Die Lehrertabelle wird 20 Datensätze enthalten
Die Tabelle link_st wird so viele Datensätze enthalten wie Links vorhanden sind (NICHT 20x1000, sondern nur für die tatsächlichen Links).

Auswahl
Sie wählen z.B. Schüler pro Lehrer mit:

SELECT s.name, t.name 
FROM student
INNER JOIN link_st l ON (l.student_id = s.id)   <--- first link student to the link-table
INNER JOIN teacher t ON (l.teacher_id = t.id)   <--- then link teacher to the link table.
ORDER BY t.id, s.id

Normalerweise sollten Sie immer einen Inner Join verwenden hier.

Einen Link erstellen
Wenn Sie einem Schüler einen Lehrer zuweisen (oder umgekehrt, das ist dasselbe) .Sie müssen nur Folgendes tun:

INSERT INTO link_st (student_id, teacher_id) 
   SELECT s.id, t.id 
   FROM student s 
   INNER JOIN teacher t ON (t.name = 'Jones')
   WHERE s.name = 'kiddo'

Dies ist ein bisschen ein Missbrauch eines inneren Joins, aber es funktioniert, solange die Namen eindeutig sind.
Wenn Sie die IDs kennen, können Sie diese natürlich direkt einfügen.
Wenn die Namen eindeutig sind nicht eindeutig, dies ist ein Fehler und sollte nicht verwendet werden.

So vermeiden Sie doppelte Links
Es ist sehr wichtig, doppelte Links zu vermeiden. Wenn Sie solche haben, können alle möglichen schlimmen Dinge passieren.
Wenn Sie verhindern möchten, dass doppelte Links in Ihre Linktabelle eingefügt werden, können Sie einen unique Index auf dem Link (empfohlen)

ALTER TABLE link_st
  ADD UNIQUE INDEX s_t (student_id, teacher_id); 

Oder Sie können den Check in der Insert-Anweisung durchführen (nicht wirklich empfohlen, aber es funktioniert).

INSERT INTO link_st (student_id, teacher_id) 
  SELECT s.id, t.id
  FROM student s
  INNER JOIN teacher t ON (t.id = 548)
  LEFT JOIN link_st l ON (l.student_id = s.id AND l.teacher_id = t.id)
  WHERE (s.id = 785) AND (l.id IS NULL)

Dadurch wird 548, 785 nur wenn ausgewählt diese Daten sind nicht bereits in link_st table und gibt nichts zurück, wenn sich diese Daten bereits in link_st befinden. Daher wird es abgelehnt, doppelte Werte einzufügen.

Wenn Sie Tabellenschulen haben, hängt es davon ab, ob ein Schüler an mehreren Schulen eingeschrieben sein kann (unwahrscheinlich, aber nehmen wir an) und Lehrer an mehreren Schulen eingeschrieben sein können. Sehr gut möglich.

table school
  id unsigned integer auto_increment primary key
  name varchar

table school_members
  id id unsigned integer auto_increment primary key
  school_id integer not null
  member_id integer not null
  is_student boolean not null

Sie können alle Schüler einer Schule wie folgt auflisten:

SELECT s.name
FROM school i
INNER JOIN school_members m ON (i.id = m.school_id)
INNER JOIN student s ON (s.id = m.member_id AND m.is_student = true)