Я не думаю, що у вас є проблеми у стосунках. Я думаю, натомість проблема полягає в тому, що за допомогою сурогатних ключів (тобто ідентифікаторів) для кожної таблиці отримана база даних не в змозі запобігти введенню робітників, департамент яких складається з однієї компанії, а класифікація - іншої та навпаки. Хороший спосіб зрозуміти це - візуалізувати схему за допомогою засобу ER Diagramming. Я буду використовувати інструмент Oracle Data Modeler , який безкоштовно завантажується.
Діаграма ЕР
Як тепер, у вас може бути 2 компанії - скажіть IBM
і Microsoft
. IBM
може мати Software Development
відділ, а Microsoft може мати Desktop Software
відділ. IBM може мати Software Engineer
класифікацію, а Microsoft може мати Software Developer
класифікацію. Тепер, оскільки у вас є сурогатний ключ, Department
а для майбутніх стосунків з дитиною втрачається Classification
той факт, що Software Development
це IBM
відділ і Desktop Software
це Microsoft
відділ. Так само і у випадку Classification
. Тому легко випадково призначити Harlan Mills
, хто є IBM
працівником Software Development
відділу, класифікація Software Developer
якого - цеMicrosoft
класифікація! Так само працівнику можна було б дати правильну класифікацію та неправильний відділ! Ось схема, що показує перший приклад:
1 Ідс представляють IBM
, а 2 Ідс представляють Microsoft
. Червоним кольором я виділив сценарій, де Harlan Mills
і Bill Gates
призначені неправильні відділи, який візуалізується 10 ідентифікатором департаменту, пов’язаним із класифікацією 200 Id і навпаки.
Варіанти вирішення
То які варіанти не допустити його? Є два негайні варіанти. Перший - усвідомити, що за допомогою сурогатного ключа для кожної таблиці ця проблема існує та запровадити додаткове програмування, щоб переконатися, що воно не відбувається. Це можна зробити в додатку, але якщо вставки та оновлення можуть відбуватися поза додатком, то все ж можуть виникати неправильні асоціації. Кращим підходом було б створити тригер, який спрацьовує після вставки та оновлення працівника, щоб переконатися, що призначений відділ має ту саму компанію, що і призначена класифікація, а якщо не вийде з ладу вставити або оновити.
Другий варіант - не використовувати сурогатні ключі для кожної таблиці. Натомість використовуйте сурогатні клавіші лише для Company
таблиці, яка є основоположною та не має батьків, а потім створіть ідентифікуючі стосунки до Department
та Classification
дочірніх таблиць. У таблицях Department
та Classification
таблицях тепер є ПК Company Id
плюс номер послідовності або ім'я для їх розрізнення. Потім відносини від Department
і Classification
до Worker
також стають, identifying
і, таким чином, ПК Worker
стає Company Id
, плюс Department Number
(я використовую порядковий номер у цьому прикладі), плюс Classification Number
. Результат є лише one
Company Id
в Worker
таблиці. Зараз неможливо призначити аWorker
до a Department
в одному Company
і до a Classification
в іншому Company
.
Чому це неможливо? Це неможливо, оскільки схема реалізує референтну цілісність між Worker
і Department
та Classification
. Якщо буде зроблена спроба вставити a Worker
для Department
одного Company
і a Classification
другого, комбінація, яка не існує у відповідній батьківській таблиці, призведе до порушення референтної цілісності, і вставка не працюватиме.
Ось оновлена схема реалізації другого варіанту:
Бажаний варіант
З двох варіантів я абсолютно віддаю перевагу другому - використовуючи ідентифікаційні зв'язки та каскадні клавіші - з двох причин. По-перше, ця опція досягає бажаного правила без додаткового програмування. Розробка тригера не є дрібницею. Він повинен бути закодований, випробуваний та підтримуваний. Забезпечення логіки тригера є оптимальним, щоб не впливати на продуктивність також не банально. Книга прикладної математики для професіоналів баз даних надає багато деталей щодо складності такого рішення. По-друге, правила передбачають, що Департамент та Класифікація не можуть існувати поза контекстом Company
, і тому схема тепер більш точно відображає реальний світ.
Це чудове запитання, оскільки воно точно показує, чому просто припускати, що кожен стіл вимагає сурогатного ключа - це погана ідея. Фабіан Паскаль має чудову публікацію в блозі саме на цю тему, показуючи, що сурогатний ключ не тільки може бути поганою ідеєю з точки зору цілісності даних, але також може призвести до того, що деякі пошуки будуть повільнішимина фізичному рівні саме тому, що потрібні з'єднання, якщо б ключі були належним чином каскадовані, було б непотрібним. Ще одна цікава тема, яку розкриває це питання, полягає в тому, що база даних не може забезпечити точність усіх даних, що вставляються в неї, щодо реального світу. Натомість він може лише переконатися, що введені в нього дані відповідають правилам, оголошеним до нього. У цьому випадку ми можемо зробити найкраще, використовуючи підхід каскадного ключа, щоб забезпечити, щоб СУБД могла підтримувати дані узгодженими щодо правила, згідно Worker
з яким з заданих даних Company
потрібно призначити Classification
а, а Department
з цього ж Company
. Але, якщо в реальному світі Microsoft
є департамент, який називається, Desktop Software
але користувач бази даних стверджує, що це замість ньогоSoftware Development
СУБД нічого не може зробити, окрім припущення, що він отримав справжній факт.