Проблема відносин між особами


19

У мене є 4 подібні таблиці (це приклад):

Company:
ID
Name
CNPJ

Department:
ID
Name
Code
ID_Company 

Classification:
ID
Name
Code
ID_Company

Workers:
Id 
Name
Code
ID_Classification
ID_Department

Припустимо, що я маю classificationс id = 20, id_company = 1. І departmentщо має id_company = 2(що представляє іншу компанію).

Це дозволить створити працівника з двох компаній, оскільки класифікація та відділ пов'язані з компанією окремо. Я не хочу, щоб це сталося, тому я думаю, що у мене є проблеми зі своїми стосунками, і я не знаю, як її вирішити.


1
Що таке "класифікація"?
Джехад Керіакі

1
Я б здогадався, classificationце аналог посаді, тобто секретар, двірник, оверлог та ін.
Ерік,

Ви хочете встановити, що працівник повинен належати до того самого відділу, що і класифікація?
Леннарт

Можливо, Департамент, Класифікація (і навіть Робітник) слід розглядати як слабкі структури, все залежно від компанії. Тоді ключ компанії буде частиною ключів відділу, класифікації та працівника. Слабка сутність є сутністю, існування якого залежить від існування іншої особи.
чудо173

Відповіді:


9

Ваша проблема пов'язана з тим, що у вашій моделі відсутній тип сутності. Розглянемо наступні ЕРД:

ERD

Зауважте, що я додав тип об'єкта перетину між DEPARTMENTі CLASSIFICATION. Цей новий тип сутності: POSITIONнадає інформацію, яка міститься у вашій моделі, про те, що певний відділ має набір завдань різних класифікацій.

Додавання POSITIONдо вашої моделі як явної сутності має кілька переваг.

  1. Це дозволяє уникнути проблеми, яка вас турбує з WORKERможливим призначенням до відділів та класифікацій у різних компаніях.
  2. Він дає вам локус для інших предикатів, які можуть бути застосовні до посади, наприклад, заробітної плати тощо.
  3. Це дозволяє зафіксувати факт існування позиції, навіть якщо на WORKERданий момент у цій позиції немає s, що є цілком можливою корисною інформацією.

Зауважте, що, щоб уникнути проблеми визначення посади для департаменту та класифікації, які є в різних компаніях, я розширив ключі обох DEPARTMENTі CLASSIFICATION, що добре з причин, про які ви можете детально прочитати у відповіді Тодда Еверета.

ПОВЕРНІТЬСЯ Вказана вище модель передбачає спрощення. Зокрема, передбачається, що кожна позиція записується лише один раз. Це може бути або не підходить правилам вашого бізнесу. Якщо вам потрібно кілька POSITIONзаписів для одного відділу та класифікація в межах компанії, ви можете ввести сурогатний ключ POSITION.


24

Я не думаю, що у вас є проблеми у стосунках. Я думаю, натомість проблема полягає в тому, що за допомогою сурогатних ключів (тобто ідентифікаторів) для кожної таблиці отримана база даних не в змозі запобігти введенню робітників, департамент яких складається з однієї компанії, а класифікація - іншої та навпаки. Хороший спосіб зрозуміти це - візуалізувати схему за допомогою засобу 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 СУБД нічого не може зробити, окрім припущення, що він отримав справжній факт.


1

Як я розумію питання, поле ID_Classification таблиці "Робітники" повинно допускати лише класифікації, визначені для відповідної компанії працівників. Отже, валідація (шляхом приєднання правила або через TRIGGERS) інформацію, вставлену / оновлену в поле Workers.ID_Classification, достатня для задоволення цієї вимоги.


1

З моїх прочитань я досі не розумію, що це за Класифікація і чому для цього потрібна ID_Company . Якщо це подібна позиція, як хтось тут згадував, я думаю, що статична таблиця, яка містить усі позиції, буде краще.

Якщо ви робите це для того, щоб легко знайти класифікацію / посаду в компанії, будь ласка, додайте простий запит / представлення для підключення класифікаційних робітників-відділів та отримання ідентифікатора фірми класифікації.

на сьогоднішній день існують розумніші перегляди або технології, такі як матеріалізовані представлення даних та індекси об’єднання, тому якщо ваша проблема - це виконання запиту, використовуйте їх.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.