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