Проблема отношения сущностей

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(который представляет другую компанию).

Это позволит создать работника из двух компаний, поскольку классификация и отдел связаны с компанией отдельно. Я не хочу, чтобы это произошло, поэтому я думаю, что у меня есть проблема с моими отношениями, и я не знаю, как ее решить.

777Anon
источник
1
Что такое «классификация»?
Джехад Кериаки
1
Я полагаю, что classificationэто аналогично должности, то есть секретаря, уборщика, повелителя и т. Д.
Эрик,
Хотите ли вы обеспечить, чтобы работник принадлежал к тому же отделу, что и классификация?
Леннарт
Возможно, отдел, классификация (и даже работник) должны рассматриваться как слабые субъекты, все в зависимости от компании. Тогда ключ компании будет частью ключей департамента, классификации и работника. Слабая сущность является сущностью, существование которого зависит от существования другого лица.
чудо173

Ответы:

9

Ваша проблема связана с тем, что в вашей модели отсутствует тип сущности. Рассмотрим следующее ERD:

ERD

Обратите внимание, что я добавил тип сущности пересечения между DEPARTMENTи CLASSIFICATION. Этот новый тип сущности: POSITIONпредоставляет информацию, которая подразумевается в вашей модели, о том, что конкретный отдел имеет набор заданий различных классификаций.

Добавление POSITIONк вашей модели в качестве явного объекта имеет несколько преимуществ.

  1. Это позволяет избежать проблемы, которая вас беспокоит из-за WORKERвозможного назначения в отделы и классификации в разных компаниях.
  2. Он дает вам локус для других предикатов, которые могут быть применимы к позиции, например, уровень зарплаты и т. Д.
  3. Это позволяет вам записывать факт существования позиции, даже если в WORKERданный момент в ней нет s, что, вполне возможно, является полезной информацией.

Обратите внимание, что во избежание проблемы определения должности для отдела и классификации в разных компаниях, я расширил ключи обоих DEPARTMENTи CLASSIFICATION, что хорошо по причинам, о которых вы можете прочитать подробно в ответе Тодда Эверетта.

ВНИМАНИЕ! Вышеуказанная модель предполагает упрощение. В частности, предполагается, что каждая позиция записывается только один раз. Это может или не может соответствовать вашим бизнес-правилам. Если вам нужно несколько POSITIONзаписей для одного и того же отдела и классификации внутри компании, вы можете ввести суррогатный ключ POSITION.

Джоэл Браун
источник
24

Я не думаю, что у вас есть проблемы с отношениями. Вместо этого я думаю, что проблема в том, что при использовании суррогатных ключей (т. Е. Идентификаторов) для каждой таблицы результирующая база данных не может помешать вставке рабочих, чей отдел принадлежит одной компании, а классификация - другой, и наоборот. Хороший способ понять это - визуализировать схему с помощью инструмента ER Diagramming. Я буду использовать инструмент Oracle Data Modeler , который можно бесплатно загрузить.

Диаграмма ER

введите описание изображения здесь

В таком виде у вас может быть 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 Id представляют IBM, а 2 Id представляют Microsoft. Я выделил красным сценарий, где Harlan Millsи Bill Gatesприсваиваются неправильные отделы, что визуализируется 10 идентификаторами отделов, связанными с идентификатором 200 классификаций, и наоборот.

Варианты разрешения

Так, каковы варианты, чтобы предотвратить его? Есть два немедленных варианта. Во-первых, нужно понять, что с помощью суррогатного ключа для каждой таблицы эта проблема существует, и ввести дополнительное программирование, чтобы убедиться, что она не возникает. Это может быть сделано в приложении, но если вставки и обновления могут происходить вне приложения, тогда все равно могут возникать неправильные ассоциации. Лучшим подходом было бы создание триггера, который запускает вставку и обновление сотрудника, чтобы убедиться, что назначенный отдел принадлежит к той же компании, что и назначенная классификация, и, если нет, выполнить вставку или обновление.

Второй вариант - не использовать суррогатные ключи для каждой таблицы. Вместо этого используйте суррогатные ключи только для Companyтаблицы, которая является фундаментальной и не имеет родителей, а затем создайте идентифицирующие связи с таблицами Departmentand и Classificationchild. DepartmentИ Classificationтаблицы теперь имеют рК Company Idплюс порядковый номер или имя , чтобы отличить их. Затем отношения от Departmentи Classificationк Workerтакже становятся, identifyingи, таким образом, PK Workerстановится Company Id, плюс Department Number(я использую порядковый номер в этом примере), плюс Classification Number. Результат есть только one Company Idв Workerтаблице. Теперь невозможно назначитьWorkerчтобы Departmentв одном Companyи чтобы Classificationв другом Company.

Почему это невозможно? Это невозможно, потому что схема реализует ссылочную целостность между Workerи Departmentи Classification. Если предпринята попытка вставить a Workerдля a 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 . Если это похоже на позицию, о которой кто-то упоминал здесь, я думаю, что статическая таблица, содержащая все позиции, была бы лучше.

Если вы делаете это для того, чтобы легко найти классификацию / должность в компании, добавьте простой запрос / представление, чтобы связать классификационные рабочие отделы и получить идентификатор компании для классификации.

в настоящее время существуют более разумные представления или технологии, такие как материализованные представления и индексы соединений, поэтому, если ваша проблема заключается в производительности запроса, используйте их.

Johns
источник