Problema de relacionamento da entidade

19

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 classificationcom id = 20, id_company = 1. E um departmentque 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.

777Anon
fonte
1
O que é 'Classificação'?
Jehad Keriaki
1
Eu acho que classificationé análogo ao posicionar ie secretário, porteiro, overlord, etc.
Erik
Deseja garantir que um trabalhador deva pertencer ao mesmo departamento da classificação?
Lennart
Talvez Departamento, Classificação (e até Trabalhador) devam ser vistos como entidades fracas, tudo dependendo da Empresa. Em seguida, a chave da empresa faria parte das chaves de departamento, classificação e trabalhador. Uma entidade fraca é uma entidade cuja existência depende da existência de outra entidade.
precisa saber é o seguinte

Respostas:

9

Seu problema decorre do fato de que há um tipo de entidade ausente no seu modelo. Considere o seguinte ERD:

ERD

Observe que eu adicionei um tipo de entidade de interseção entre DEPARTMENTe CLASSIFICATION. Esse novo tipo de entidade: POSITIONfornece as informações implícitas no seu modelo, que um departamento específico possui um conjunto de tarefas de várias classificações.

Adicionar POSITIONao seu modelo como uma entidade explícita tem algumas vantagens.

  1. Evita o problema com o qual você está WORKERpotencialmente sendo atribuído a departamentos e classificações em diferentes empresas.
  2. Ele fornece um local para outros predicados que podem ser aplicáveis ​​a uma posição, como nota salarial etc.
  3. Ele permite que você registre o fato de que uma posição existe, mesmo que não haja WORKERs 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 DEPARTMENTe CLASSIFICATION, 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 POSITIONregistros para o mesmo departamento e classificação em uma empresa, poderá introduzir uma chave substituta POSITION.

Joel Brown
fonte
24

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

insira a descrição da imagem aqui

Tal como está, você poderia ter duas empresas - digamos IBMe Microsoft. IBMpode ter um Software Developmentdepartamento e a Microsoft pode ter um Desktop Softwaredepartamento. A IBM pode ter uma Software Engineerclassificação e a Microsoft pode ter uma Software Developerclassificação. Agora, porque você tem uma chave substituta para Departmente Classification, o fato de Software Developmentser um IBMdepartamento Desktop Softwareé um Microsoftdepartamento perdido para futuros relacionamentos com filhos. Este também é o caso com Classification. Portanto, é fácil atribuir acidentalmente Harlan Millsquem é IBMfuncionário do Software Developmentdepartamento Software Developercuja classificação é umaMicrosoftclassificação! Da mesma forma, o trabalhador poderia receber a classificação correta e o departamento errado! Aqui está um diagrama mostrando o primeiro exemplo:

insira a descrição da imagem aqui

Os 1 IDs representam IBMe os 2 IDs representam Microsoft. Eu já destacados em vermelho o cenário onde Harlan Millse Bill Gatessã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 Companytabela, que é fundamental e não possui pais, e crie relacionamentos de identificação para as tabelas Departmente Classificationfilhos. As tabelas Departmente Classificationagora têm uma PK do Company Idnúmero ou nome da sequência mais para distingui-las. Então, os relacionamentos de Departmente Classificationpara Workertambém se tornam identifyinge, portanto, o PK de Workerse torna o Company Id, mais o Department Number(estou usando um número de sequência neste exemplo), mais o Classification Number. O resultado é que existe apenas one Company Idna Workertabela. Agora é impossível atribuir umWorkerpara um Departmentem um Companye para um Classificationem outro Company.

Por que isso é impossível? É impossível porque o esquema implementa integridade referencial entre Workere Departmente Classification. Se for feita uma tentativa de inserir um Workerpara um Departmentem um Companye um Classificationde 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: insira a descrição da imagem aqui

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 Companye, 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 Workerde um dado Companyprecisa ser atribuído Classificatione um Departmentdo mesmo Company. Porém, se no mundo real Microsofthouver um departamento chamado, Desktop Softwaremas 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.

Todd Everett
fonte
1

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.

Haris
fonte
1

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.

Johns
fonte