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