Я не думаю, что у вас есть проблемы с отношениями. Вместо этого я думаю, что проблема в том, что при использовании суррогатных ключей (т. Е. Идентификаторов) для каждой таблицы результирующая база данных не может помешать вставке рабочих, чей отдел принадлежит одной компании, а классификация - другой, и наоборот. Хороший способ понять это - визуализировать схему с помощью инструмента 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
таблицы, которая является фундаментальной и не имеет родителей, а затем создайте идентифицирующие связи с таблицами Department
and и Classification
child. 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
СУБД ничего не может сделать, кроме как предположить, что ей был дан настоящий факт.