У меня есть 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
(который представляет другую компанию).
Это позволит создать работника из двух компаний, поскольку классификация и отдел связаны с компанией отдельно. Я не хочу, чтобы это произошло, поэтому я думаю, что у меня есть проблема с моими отношениями, и я не знаю, как ее решить.
database-design
constraint
777Anon
источник
источник
classification
это аналогично должности, то есть секретаря, уборщика, повелителя и т. Д.Ответы:
Ваша проблема связана с тем, что в вашей модели отсутствует тип сущности. Рассмотрим следующее ERD:
Обратите внимание, что я добавил тип сущности пересечения между
DEPARTMENT
иCLASSIFICATION
. Этот новый тип сущности:POSITION
предоставляет информацию, которая подразумевается в вашей модели, о том, что конкретный отдел имеет набор заданий различных классификаций.Добавление
POSITION
к вашей модели в качестве явного объекта имеет несколько преимуществ.WORKER
возможного назначения в отделы и классификации в разных компаниях.WORKER
данный момент в ней нет s, что, вполне возможно, является полезной информацией.Обратите внимание, что во избежание проблемы определения должности для отдела и классификации в разных компаниях, я расширил ключи обоих
DEPARTMENT
иCLASSIFICATION
, что хорошо по причинам, о которых вы можете прочитать подробно в ответе Тодда Эверетта.ВНИМАНИЕ! Вышеуказанная модель предполагает упрощение. В частности, предполагается, что каждая позиция записывается только один раз. Это может или не может соответствовать вашим бизнес-правилам. Если вам нужно несколько
POSITION
записей для одного и того же отдела и классификации внутри компании, вы можете ввести суррогатный ключPOSITION
.источник
Я не думаю, что у вас есть проблемы с отношениями. Вместо этого я думаю, что проблема в том, что при использовании суррогатных ключей (т. Е. Идентификаторов) для каждой таблицы результирующая база данных не может помешать вставке рабочих, чей отдел принадлежит одной компании, а классификация - другой, и наоборот. Хороший способ понять это - визуализировать схему с помощью инструмента 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
и, таким образом, PKWorker
становитсяCompany Id
, плюсDepartment Number
(я использую порядковый номер в этом примере), плюсClassification Number
. Результат есть толькоone
Company Id
вWorker
таблице. Теперь невозможно назначитьWorker
чтобыDepartment
в одномCompany
и чтобыClassification
в другомCompany
.Почему это невозможно? Это невозможно, потому что схема реализует ссылочную целостность между
Worker
иDepartment
иClassification
. Если предпринята попытка вставить aWorker
для aDepartment
в одномCompany
и aClassification
в другом, комбинация, которая не существует в соответствующей родительской таблице, вызовет нарушение ссылочной целостности, и вставка не будет работать.Вот обновленная схема реализации второго варианта:
Предпочтительный вариант
Из двух вариантов я абсолютно предпочитаю второй - использование идентифицирующих отношений и каскадных ключей - по двум причинам. Во-первых, эта опция достигает желаемого правила без дополнительного программирования. Разработка триггера не тривиальна. Это должно быть закодировано, проверено и поддержано. Обеспечение оптимальной логики запуска, чтобы не влиять на производительность, также не является тривиальным. В книге « Прикладная математика для специалистов по базам данных» содержится много подробностей о сложности такого решения. Во-вторых, правила подразумевают, что Департамент и Классификация не могут существовать вне контекста
Company
, и поэтому схема теперь более точно отражает реальный мир.Это отличный вопрос, потому что он показывает, почему просто предполагать, что для каждой таблицы требуется суррогатный ключ, - плохая идея. У Фабиана Паскаля есть отличная запись в блоге только на эту тему, показывающую, что суррогатный ключ не только может быть плохой идеей с точки зрения целостности данных, но и может привести к замедлению некоторых операций поиска.на физическом уровне именно потому, что объединения требуются, что, если бы ключи были должным образом каскадированы, были бы ненужными. Другая интересная тема, которую раскрывает этот вопрос, заключается в том, что база данных не может гарантировать, что все данные, введенные в нее, являются точными по отношению к реальному миру. Вместо этого он может только гарантировать, что данные, вставленные в него, соответствуют заявленным правилам. В этом случае мы можем сделать наилучший возможное с помощью подхода ключа каскадного для обеспечения СУБД может хранить данные соответствует по отношению к правилу , что
Worker
даннойCompany
потребности быть назначенClassification
иDepartment
из этого жеCompany
. Но, если в реальном миреMicrosoft
есть отдел,Desktop Software
но пользователь базы данных утверждает, что отделSoftware Development
СУБД ничего не может сделать, кроме как предположить, что ей был дан настоящий факт.источник
Насколько я понимаю, вопрос заключается в том, что поле ID_Classification таблицы «Рабочие» должно разрешать только классификации, определенные для соответствующей компании работника. Следовательно, проверка (путем присоединения ПРАВИЛА или с помощью TRIGGERS) информации, вставленной / обновленной в поле Workers.ID_Classification, достаточна для удовлетворения этого требования.
источник
Из моих чтений я до сих пор не понимаю, что это за классификация и зачем ей нужна ID_Company . Если это похоже на позицию, о которой кто-то упоминал здесь, я думаю, что статическая таблица, содержащая все позиции, была бы лучше.
Если вы делаете это для того, чтобы легко найти классификацию / должность в компании, добавьте простой запрос / представление, чтобы связать классификационные рабочие отделы и получить идентификатор компании для классификации.
в настоящее время существуют более разумные представления или технологии, такие как материализованные представления и индексы соединений, поэтому, если ваша проблема заключается в производительности запроса, используйте их.
источник