Eu tenho 4 tabelas relacionadas como esta (é um exemplo):
Company:
ID
Name
CNPJ
Department:
ID
Name
Code
ID_Company
Classification:
ID
Name
Code
ID_Company
Workers:
Id
Name
Code
ID_Classification
ID_Department
Suponha que eu tenha um classification
com id = 20, id_company = 1
. E um department
que tem id_company = 2
(que representa outra empresa).
Isso permitirá a criação de um trabalhador de duas empresas, porque a classificação e o departamento estão vinculados à empresa separadamente. Não quero que isso aconteça, então acho que tenho um problema com meus relacionamentos e não sei como resolvê-lo.
database-design
constraint
777Anon
fonte
fonte
classification
é análogo ao posicionar ie secretário, porteiro, overlord, etc.Respostas:
Seu problema decorre do fato de que há um tipo de entidade ausente no seu modelo. Considere o seguinte ERD:
Observe que eu adicionei um tipo de entidade de interseção entre
DEPARTMENT
eCLASSIFICATION
. Esse novo tipo de entidade:POSITION
fornece as informações implícitas no seu modelo, que um departamento específico possui um conjunto de tarefas de várias classificações.Adicionar
POSITION
ao seu modelo como uma entidade explícita tem algumas vantagens.WORKER
potencialmente sendo atribuído a departamentos e classificações em diferentes empresas.WORKER
s atualmente na posição, o que é uma informação possivelmente muito útil.Observe que, para evitar o problema de uma posição ser definida para um departamento e uma classificação em empresas diferentes, expandi as chaves de ambos
DEPARTMENT
eCLASSIFICATION
, o que é bom pelas razões pelas quais você pode ler detalhadamente na resposta de Todd Everett.CUIDADO O modelo acima pressupõe uma simplificação. Especificamente, assume que cada posição é registrada apenas uma vez. Isso pode ou não ser adequado às suas regras de negócios. Se você precisar de vários
POSITION
registros para o mesmo departamento e classificação em uma empresa, poderá introduzir uma chave substitutaPOSITION
.fonte
Eu não acho que você tenha um problema com os relacionamentos. Penso que, em vez disso, o problema é que, usando chaves substitutas (ou seja, IDs) para cada tabela, o banco de dados resultante é incapaz de impedir a inserção de trabalhadores cujo departamento é de uma empresa, enquanto a classificação é de outra e vice-versa. Uma boa maneira de entender isso é visualizar o esquema usando uma ferramenta de diagramação de ER. Vou usar o Oracle Data Modeler ferramenta que é um download gratuito.
Diagrama ER
Tal como está, você poderia ter duas empresas - digamos
IBM
eMicrosoft
.IBM
pode ter umSoftware Development
departamento e a Microsoft pode ter umDesktop Software
departamento. A IBM pode ter umaSoftware Engineer
classificação e a Microsoft pode ter umaSoftware Developer
classificação. Agora, porque você tem uma chave substituta paraDepartment
eClassification
, o fato deSoftware Development
ser umIBM
departamentoDesktop Software
é umMicrosoft
departamento perdido para futuros relacionamentos com filhos. Este também é o caso comClassification
. Portanto, é fácil atribuir acidentalmenteHarlan Mills
quem éIBM
funcionário doSoftware Development
departamentoSoftware Developer
cuja classificação é umaMicrosoft
classificação! Da mesma forma, o trabalhador poderia receber a classificação correta e o departamento errado! Aqui está um diagrama mostrando o primeiro exemplo:Os 1 IDs representam
IBM
e os 2 IDs representamMicrosoft
. Eu já destacados em vermelho o cenário ondeHarlan Mills
eBill Gates
são atribuídos aos departamentos erradas, que é visualizado pela Id 10 departamento associado à classificação 200 Id e vice-versa.Opções para resolver
Então, quais são as opções para impedir que ele aconteça? Existem duas opções imediatas. A primeira é perceber que, usando uma chave substituta para todas as tabelas, esse problema existe e introduzir programação adicional para verificar se isso não ocorre. Isso pode ser feito no aplicativo, mas se inserções e atualizações puderem ocorrer fora do aplicativo, associações incorretas ainda poderão ocorrer. Uma abordagem melhor seria criar um gatilho que seja acionado na inserção e atualização de um funcionário para garantir que o departamento designado seja da mesma empresa que a classificação atribuída e, caso contrário, falhe na inserção ou atualização.
A segunda opção é não usar chaves substitutas para todas as tabelas. Em vez disso, use as chaves substitutas apenas para a
Company
tabela, que é fundamental e não possui pais, e crie relacionamentos de identificação para as tabelasDepartment
eClassification
filhos. As tabelasDepartment
eClassification
agora têm uma PK doCompany Id
número ou nome da sequência mais para distingui-las. Então, os relacionamentos deDepartment
eClassification
paraWorker
também se tornamidentifying
e, portanto, o PK deWorker
se torna oCompany Id
, mais oDepartment Number
(estou usando um número de sequência neste exemplo), mais oClassification Number
. O resultado é que existe apenasone
Company Id
naWorker
tabela. Agora é impossível atribuir umWorker
para umDepartment
em umCompany
e para umClassification
em outroCompany
.Por que isso é impossível? É impossível porque o esquema implementa integridade referencial entre
Worker
eDepartment
eClassification
. Se for feita uma tentativa de inserir umWorker
para umDepartment
em umCompany
e umClassification
de outro, a combinação que não existe na tabela pai correspondente disparará uma violação de integridade referencial e a inserção não funcionará.Aqui está um diagrama atualizado de uma implementação da segunda opção:
Opção preferida
Das duas opções, prefiro absolutamente a segunda - usando os relacionamentos de identificação e as chaves em cascata - por dois motivos. Primeiro, esta opção atinge a regra desejada sem programação adicional. Desenvolver um gatilho não é trivial. Ele deve ser codificado, testado e mantido. Garantir que a lógica do acionador seja ideal para não afetar o desempenho também não é trivial. O livro Matemática Aplicada para Profissionais de Banco de Dados fornece muitos detalhes sobre a complexidade dessa solução. Segundo, as regras implicam que um Departamento e uma Classificação não podem existir fora do contexto do
Company
e, portanto, o esquema agora reflete com mais precisão o mundo real.Essa é uma ótima pergunta, pois mostra exatamente por que simplesmente supor que todas as tabelas exigem uma chave substituta é uma má idéia. Fabian Pascal tem um excelente post sobre este tópico, mostrando que uma chave substituta não só pode ser uma má ideia do ponto de vista da integridade de dados, como também pode resultar em lentidão nas recuperaçõesno nível físico, precisamente porque são necessárias junções que, se as chaves tivessem sido devidamente conectadas em cascata, seriam desnecessárias. Outro tópico interessante que essa pergunta revela é que um banco de dados não pode garantir que todos os dados inseridos nele sejam precisos em relação ao mundo real. Em vez disso, ele pode garantir apenas que os dados inseridos nele sejam consistentes com as regras declaradas a ele. Nesse caso, podemos fazer o melhor possível, usando a abordagem de chave em cascata para garantir que o DBMS possa manter os dados consistentes com relação à regra de que um
Worker
de um dadoCompany
precisa ser atribuídoClassification
e umDepartment
do mesmoCompany
. Porém, se no mundo realMicrosoft
houver um departamento chamado,Desktop Software
mas o usuário do banco de dados afirmar que o departamento estáSoftware Development
o DBMS não pode fazer nada além de assumir que foi dado um fato verdadeiro.fonte
Pelo que entendi a pergunta, o campo ID_Classification da tabela 'Trabalhadores' deve permitir apenas as classificações definidas para a empresa do respectivo trabalhador. Portanto, validar (anexando uma REGRA ou por meio de TRIGGERS) as informações inseridas / atualizadas no campo Workers.ID_Classification é adequado para atender a esse requisito.
fonte
Pelas minhas leituras, ainda não entendo o que é essa Classificação e por que ela precisa ter o ID_Company . Se é como uma posição como alguém mencionado aqui, eu acho que uma tabela estática para conter todas as posições seria melhor.
Se você estiver fazendo isso para encontrar facilmente uma classificação / posição em uma empresa, adicione uma consulta / visão simples para conectar a classificação-trabalhadores-departamentos e recuperar o ID da empresa da classificação.
hoje em dia, existem visualizações ou tecnologias mais inteligentes, como visualizações materializadas e índices de junção; portanto, se o seu problema for o desempenho da consulta, use-os.
fonte