+1 dla Matta Fenwicka. Dodałbym, że chcesz być trochę ostrożny z ograniczeniami klucza obcego. Zasadniczo masz dwie opcje, z których obie mogą wyglądać dość podobnie, w zależności od wyboru kluczy podstawowych.
Opcja pierwsza to:Zapomnij o prostym przecięciu między TEACHER
i INSTRUMENT
i zastąp go złożonym skrzyżowaniem, które zawiera teacher_id
, instrument_id
i level_id
. Wszystkie trzy z tych kolumn będą (złożonym) kluczem podstawowym tej tabeli przecięcia. W tej opcji masz zdefiniowane ograniczenia klucza obcego w teacher_id
i instrument_id
(i level_id
jeśli w rzeczywistości jest to klucz obcy do LEVEL
tabeli, a nie tylko liczby całkowitej lub kodu ciągu).
Opcja druga jest:Zachowaj proste przecięcie między TEACHER
i INSTRUMENT
(nazwijmy to TEACHER_INSTRUMENT
nawet jeśli jest to niewyobrażalne) i dodaj tabelę podrzędną, która definiuje poziomy, których można uczyć. Ta podrzędna tabela podrzędna (nazwijmy ją SKILL
) ma level_id
i klucz obcy do TEACHER_INSTRUMENT
. Jeśli klucz podstawowy TEACHER_INSTRUMENT
jest kombinacją teacher_id
i instrument_id
następnie SKILL
tabela będzie miała te same trzy kolumny, co w opcji pierwszej. Co wyróżnia tę opcję? Ograniczenie klucza obcego z SKILL
musi być przy stole skrzyżowania, a nie TEACHER
i INSTRUMENT
.
Dlaczego to ważne? Jeśli wybierzesz opcję pierwszą, być może będziesz potrzebować dodatkowej logiki zapytań, aby uzyskać w pełni zapełnioną siatkę umiejętności, ponieważ nie ma ograniczenia integralności referencyjnej, które można zdefiniować, co zapewni, że wszystkie poziomy umiejętności zostaną wypełnione dla każdej kombinacji nauczyciela/instrumentu.
Z drugiej strony, jeśli wybierzesz opcję drugą, masz tę zaletę, że oddzielisz obawy między tym, kto może korzystać z czego, a jak dobrze może tego uczyć.
To, czego chcesz uniknąć, to mieć jedną tabelę, która zawiera tylko relację nauczyciel/instrument, a następnie drugą, która (niezależnie) powtarza tę relację, ale dodaje szczegóły poziomu umiejętności. Jeśli to zrobisz, ryzykujesz, że te dwie rzeczy nie będą zsynchronizowane.