+1 pro Matta Fenwicka. Dodal bych, že chcete být trochu opatrní s omezeními cizích klíčů. V zásadě máte dvě možnosti, z nichž obě mohou nakonec vypadat dost podobně, v závislosti na vašem výběru primárních klíčů.
Možnost jedna je:Zapomeňte na jednoduchý průsečík mezi TEACHER
a INSTRUMENT
a nahradit jej složitým průnikem, který obsahuje teacher_id
, instrument_id
a level_id
. Všechny tři tyto sloupce by byly (složeným) primárním klíčem této průsečíkové tabulky. V této možnosti máte na teacher_id
definována omezení cizího klíče a instrument_id
(a level_id
pokud je to ve skutečnosti cizí klíč k LEVEL
tabulka a ne pouze celé číslo nebo řetězcový kód).
Možnost dvě je:Udržujte jednoduchý průsečík mezi TEACHER
a INSTRUMENT
(říkejme tomu TEACHER_INSTRUMENT
i když to není nápadité) a přidejte tabulku podřízeného potomka, která definuje úrovně, které lze vyučovat. Tato podřízená tabulka (říkejme jí SKILL
) má level_id
a cizí klíč k TEACHER_INSTRUMENT
. Pokud je primární klíč TEACHER_INSTRUMENT
je kombinací teacher_id
a instrument_id
pak SKILL
tabulka bude mít stejné tři sloupce jako v možnosti jedna. Čím se tato možnost liší? Omezení cizího klíče z SKILL
musí být k průsečíkové tabulce, nikoli k TEACHER
a INSTRUMENT
.
Proč je to důležité? Pokud zvolíte možnost jedna, možná budete potřebovat nějakou extra logiku dotazu, abyste získali plně vyplněnou mřížku dovedností, protože neexistuje žádné omezení referenční integrity, které můžete definovat a které zajistí, že všechny úrovně dovedností budou vyplněny pro každou kombinaci učitel/nástroj.
Na druhou stranu, pokud zvolíte možnost dvě, máte výhodu oddělení zájmů mezi tím, kdo co může používat a jak dobře to může učit.
Čemu se chcete vyhnout, je mít jednu tabulku, která obsahuje pouze vztah učitel/nástroj, a pak druhou, která (nezávisle) tento vztah opakuje, ale přidává podrobnosti o úrovni dovednosti. Pokud to uděláte, riskujete, že tyto dvě věci nebudou synchronizovány.