sql >> Database >  >> RDS >> Mysql

MySQL:toewijzingstabellen begrijpen

Bij het gebruik van veel-op-veel-relaties is de enige realistische manier om hiermee om te gaan een toewijzingstabel.

Laten we zeggen dat we een school hebben met docenten en studenten, een student kan meerdere docenten hebben en vice versa.

Dus we maken 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)

De tabel met leerlingen zal 1000 records hebben
De tabel van de leraar zal 20 records hebben
De tabel link_st zal evenveel records hebben als er links zijn (NIET 20x1000, maar alleen voor de daadwerkelijke links).

Selectie
U selecteert b.v. studenten per docent met:

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

Normaal gesproken zou je altijd een inner join moeten gebruiken hier.

Een link maken
Als je een leraar toewijst aan een leerling (of andersom, dat is hetzelfde) .U hoeft alleen het volgende te doen:

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'

Dit is een beetje misbruik van een inner join, maar het werkt zolang de namen uniek zijn.
Als je de id's kent, kun je die natuurlijk direct invoegen.
Als de namen zijn niet uniek dit wordt een mislukt en mag niet worden gebruikt.

Dubbele links vermijden
Het is erg belangrijk om dubbele links te vermijden, er zullen allerlei slechte dingen gebeuren als je die hebt.
Als je wilt voorkomen dat dubbele links in je linktabel worden ingevoegd, kun je een uniek index op de link (aanbevolen)

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

Of je kunt de check in de insert-instructie doen (niet echt aanbevolen, maar het werkt).

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)

Dit selecteert alleen 548, 785 als die gegevens staan ​​nog niet in de link_st tabel, en zal niets retourneren als die gegevens al in link_st staan. Het zal dus weigeren dubbele waarden in te voegen.

Als je een tafelschool hebt, hangt het ervan af of een student op meerdere scholen kan worden ingeschreven (onwaarschijnlijk, maar laten we aannemen) en docenten kunnen op meerdere scholen worden ingeschreven. Heel goed mogelijk.

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

Je kunt alle studenten in een school als volgt weergeven:

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)


  1. De binnenkant van WITH ENCRYPTIE

  2. Item verwijderen uit ListView en Database met OnItemClickListener

  3. laravel 5.6 bulksgewijs invoegen van json-gegevens

  4. Grote transacties afhandelen met streamingreplicatie en MariaDB 10.4