Pergunta

O que é a melhor maneira de modelar o seguinte ...

Suponha que eu tenho dois objetos: Agency e Publisher, e ambos têm um 1-para-n relacionamento com Employee. Esta é uma verdadeira relação de um-para-n, como cada Employee só pode trabalho para uma Agency ou um Publisher. Vamos supor também que eu não posso introduzir um supertipo (por exemplo Employer) que prende a 1-para-n relação.

A minha solução preferida é ter uma chave estrangeira em Employee que pode link para uma chave primária de Agency ou Publisher (todas as minhas chaves primárias são IDs de 64 bits que são únicas em todo o banco de dados). No entanto, agora eu não vou ser capaz de mapear uma associação bidirecional, sem indicar em Employee se esta é uma relação Agency ou Publisher.

A minha outra opção é usar duas tabelas, AgencyEmployee e PublisherEmployee, que podem então ser ligados tão tradicional 1-para-n associações bidirecionais.

O que você considera as melhores práticas nesta situação?

Update: Obrigado pelas respostas grandes em tal curto período de tempo! O que você acha da seguinte solução: As chaves estrangeiras em Employee tanto para Agency e Publisher, como agency_id e publisher_id?

Foi útil?

Solução

A melhor prática provavelmente seria a introdução de uma classe empregador.

Divisória empregado em AgencyEmployee e PublisherEmployee, por outro lado, seria uma coisa má ™ para fazer.

Se introduzir empregador estava fora de questão, gostaria de indicar o tipo de empregador (Agência ou Publisher) em Employee.

Resposta à pergunta actualização:

Essa é uma opção, mas employer_type é melhor porque:

  1. Você pode querer adicionar outros tipos de empregadores no futuro
  2. Haverá um campo vazio em cada linha da tabela Funcionários.

Outras dicas

Parece que isso poderia ser modelado como uma ternário relação . Veja se você gosta da abordagem adoptada neste artigo MSDN.

Eu tenho usado essa abordagem:

Employee.EmployerType ( 'Agência' ou 'Editor')

Employee.EmployerID (agencyId ou PublisherID)

Ele funciona ok, mas você precisa de uma instrução case em um monte de seu SQL. Também se você estiver usando um ORM você solta a relação FK.

Eu estou movendo maior parte do meu código para o n: m relacionamentos para que eu possa tirar proveito do nosso apoio ORMs FK

.

É evidente que uma entidade empregador seria preferível, mas caso contrário ...

Tendo AgencyEmployee & PublisherEmployee meios tabelas será difícil determinar se um funcionário pertence a uma categoria ou outra.

Então, ao invés eu acrescentaria e EmployerType coluna para a tabela Funcionários; ele adiciona um pouco de complexidade extra para suas consultas SQL subseqüentes, mas funciona dentro das limitações que você deu.

Fora de interesse, por que você será capaz de adicionar AgencyEmployee & PublisherEmployee tabelas, mas não adicionar uma tabela Empregador? Apenas curioso ...

A +1 para Can Berk Guder.

Tecnicamente, a introdução de um meio supertipo empregador que você introduzir uma relação de empregador com todos os atributos comuns a Agência e Publisher, uma AgencySpecific (não sei como chamá-lo) relação com a chave Empregador e todos os atributos específicos do Agência ea chave Employer como uma chave estrangeira, então Agência como uma consulta ou exibição que apenas se junta AgencySpecific com Empregador, e da mesma forma para o Publisher.

Pode ser um pouco complicado ter Agência e disseminação de dados Editor através de duas tabelas que você tem que juntar todas as vezes, mas a alternativa é escrever a maioria de suas pesquisas relacionadas com funcionários duas vezes, uma vez usando Agência e uma vez usando o Publisher, e, em seguida, artesanato seus sindicatos para combinar os resultados. (Eu não vi um construtor de consulta que ajuda com coisas básicas como este.) Eu tinha que fazer isso para um projeto que usou a abordagem "não supertipos" e eu não quero fazê-lo novamente.

BTW relacionamentos ternários e até mesmo n-para-n relações não são boas práticas de projeto, se você me perguntar. Usando apenas as funções (ou seja, 1-a-n e 1-a-1), por exemplo restrições tornam-se muito mais fácil de formular.

Minha preferência pessoal seria ter uma tabela que você assumir expressamente não pode ser usada (o supertipo da Agência e Publisher; Employer)

Uma alternativa simples seria a de simplesmente não fazer cumprir a restrição de chave estrangeira. Isso não é necessariamente problemática, desde que todas as modificações para a estrutura de dados é feito através de procedimentos armazenados que você controla.

A minha preferência final seria semelhante à sua sugestão, de ter uma tabela para AgencyEmployees e um para PublisherEmployees. Mas eu gostaria de separar isso um passo adiante ...

Table1: Agency              (id, name, etc)
Table2: Publisher           (id, name, etc)
Table3: Employee            (id, name, etc)
Table4: AgencyEmployees     (agency_id, employee_id)
Table5: PublisherEmployees  (publisher_id, employee_id)


Uma razão que eu faria isso é que se torna trivial para fazer este tempo dependente. Funcionários começar, sair e se movimentar entre as empresas. A seguir ligeira alteração às referidas lhe permitiria controlar isso ...

Table1: Agency              (id, name, etc)
Table2: Publisher           (id, name, etc)
Table3: Employee            (id, name, etc)
Table4: AgencyEmployees     (agency_id,    employee_id, start_date, leave_date)
Table5: PublisherEmployees  (publisher_id, employee_id, start_date, leave_date)

Esta não impõe um empregador por empregado a qualquer momento, mas que pode ser aplicada por seus procedimentos armazenados, GUI, etc ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top