Při použití vztahů many-to-many je jediným realistickým způsobem, jak to zvládnout, pomocí mapovací tabulky.
Řekněme, že máme školu s učiteli a studenty, student může mít více učitelů a naopak.
Takže uděláme 3 stoly
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)
Tabulka studentů bude mít 1000 záznamů
Tabulka učitelů bude mít 20 záznamů
Tabulka link_st bude mít tolik záznamů, kolik je odkazů (NE 20x1000, ale pouze pro skutečné odkazy).
Výběr
Vyberete např. studentů na učitele pomocí:
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
Normálně byste měli vždy používat inner join
zde.
Vytvoření odkazu
Když studentovi přidělíte učitele (nebo naopak, to je totéž) .Potřebujete pouze:
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'
Toto je trochu nesprávné použití vnitřního spojení, ale funguje to, pokud jsou jména jedinečná.
Pokud znáte ID, můžete je samozřejmě vložit přímo.
Pokud jsou jména není unikátní, bude to selhání a neměl by se používat.
Jak se vyhnout duplicitním odkazům
Je velmi důležité vyhnout se duplicitním odkazům, pokud je máte, stanou se nejrůznější špatné věci.
Pokud chcete zabránit vkládání duplicitních odkazů do tabulky odkazů, můžete prohlásit unique
index na odkazu (doporučeno)
ALTER TABLE link_st
ADD UNIQUE INDEX s_t (student_id, teacher_id);
Nebo můžete provést kontrolu v příkazu insert (není to moc doporučeno, ale funguje to).
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)
Tím se vybere pouze 548, 785 pokud tato data již nejsou v link_st
tabulka a nevrátí nic, pokud jsou tato data již v odkazu_st. Odmítne tedy vložit duplicitní hodnoty.
Pokud máte stolní školy, záleží, zda může být student zapsán na více školách (nepravděpodobné, ale předpokládejme) a učitelé mohou být zapsáni na více školách. Velmi možné.
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
Všechny studenty ve škole můžete uvést takto:
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)