+1 за Мат Фенуик. Бих добавил, че искате да бъдете малко внимателни с ограниченията на външния ключ. По същество имате две опции, като и двете може да изглеждат доста сходни, в зависимост от избора ви на първични ключове.
Опция първа е:Забравете простото пресичане между TEACHER
и INSTRUMENT
и го заменете със сложно кръстовище, което включва teacher_id
, instrument_id
и level_id
. И трите от тези колони биха били (съставен) първичен ключ на тази пресечна таблица. В тази опция имате ограничения за външен ключ, дефинирани в teacher_id
и instrument_id
(и level_id
ако това всъщност е външен ключ към LEVEL
таблица, а не само цяло число или код на низ).
Втори вариант е:Запазете простото пресичане между TEACHER
и INSTRUMENT
(нека го наречем TEACHER_INSTRUMENT
въпреки че това е лишено от въображение) и добавете подчинена таблица, която дефинира нивата, които могат да се преподават. Тази подчинена таблица (нека я наречем SKILL
) има level_id
и външен ключ към TEACHER_INSTRUMENT
. Ако първичният ключ на TEACHER_INSTRUMENT
е комбинацията от teacher_id
и instrument_id
след това SKILL
таблицата ще има същите три колони като в опция първа. Какво прави тази опция различна? Ограничението на външния ключ от SKILL
трябва да е до пресечната маса, а не до TEACHER
и INSTRUMENT
.
Защо това е важно? Ако изберете една опция, може да се наложи да имате допълнителна логика на заявка, за да получите напълно попълнена мрежа от умения, тъй като няма ограничение за референтна цялост, което можете да дефинирате, което ще гарантира, че всички нива на умения се попълват за всяка комбинация учител/инструмент.
От друга страна, ако изберете вариант две, имате предимството да разделите притесненията между това кой какво може да използва и колко добре може да го преподава.
Това, което искате да избегнете, е да имате една таблица, която съдържа само връзката учител/инструмент и след това втора, която (независимо) повтаря тази връзка, но добавя подробности за нивото на умения. Ако направите това, рискувате тези две неща да не се синхронизират.