Versão curta
Eu tenho que adicionar um número fixo de propriedades adicionais a cada par em uma associação muitos-para-muitos existente. Passando para os diagramas abaixo, qual das Opções 1-4 é a melhor maneira, em termos de vantagens e desvantagens, de conseguir isso estendendo o Caso Base? Ou existe uma alternativa melhor que eu não considerei aqui?
Versão mais longa
Atualmente, tenho duas tabelas em um relacionamento muitos para muitos, por meio de uma tabela de junção intermediária. Agora preciso adicionar links adicionais às propriedades que pertencem ao par de objetos existentes. Eu tenho um número fixo dessas propriedades para cada par, embora uma entrada na tabela de propriedades possa ser aplicada a vários pares (ou mesmo ser usada várias vezes para um par). Estou tentando determinar a melhor maneira de fazer isso e estou tendo problemas para resolver como pensar na situação. Semanticamente, parece que posso descrevê-lo como um dos seguintes igualmente bem:
- Um par vinculado a um conjunto de um número fixo de propriedades adicionais
- Um par vinculado a muitas propriedades adicionais
- Muitos (dois) objetos vinculados a um conjunto de propriedades
- Muitos objetos vinculados a muitas propriedades
Exemplo
Eu tenho dois tipos de objetos, X e Y, cada um com IDs exclusivos, e uma tabela de vínculo objx_objy
com colunas x_id
e y_id
, que juntos formam a chave primária do link. Cada X pode estar relacionado a muitos Ys e vice-versa. Essa é a configuração do meu relacionamento muitos-para-muitos.
Caso base
Agora, adicionalmente, tenho um conjunto de propriedades definidas em outra tabela e um conjunto de condições sob as quais um determinado par (X, Y) deve ter a propriedade P. O número de condições é fixo e o mesmo para todos os pares. Eles basicamente dizem "Na situação C1, o par (X1, Y1) possui a propriedade P1", "Na situação C2, o par (X1, Y1) possui a propriedade P2" e assim por diante, para três situações / condições para cada par na junção mesa.
Opção 1
Na minha situação atual há exatamente três tais condições, e eu não tenho nenhuma razão para esperar que a aumentar, então uma possibilidade é adicionar colunas c1_p_id
, c2_p_id
e c3_p_id
para featx_featy
, especificando para um determinado x_id
e y_id
, que a propriedade p_id
para uso em cada um dos três casos .
Isso não parece uma ótima idéia para mim, porque complica o SQL para selecionar todas as propriedades aplicadas a um recurso e não é facilmente escalável para mais condições. No entanto, ele impõe a exigência de um certo número de condições por par (X, Y). De fato, é a única opção aqui que faz isso.
opção 2
Crie uma tabela de condições cond
e adicione o ID da condição à chave primária da tabela de junção.
Uma desvantagem disso é que ele não especifica o número de condições para cada par. Outra é que, quando estou apenas considerando o relacionamento inicial, com algo como
SELECT objx.*, objy.* FROM objx
INNER JOIN objx_objy ON objx_objy.x_id = objx.id
INNER JOIN objy ON objy.id = objx_objy.y_id
Em seguida, tenho que adicionar uma DISTINCT
cláusula para evitar entradas duplicadas. Isso parece ter perdido o fato de que cada par deveria existir apenas uma vez.
Opção 3
Crie um novo 'ID do par' na tabela de junção e, em seguida, tenha uma segunda tabela de links entre a primeira e as propriedades e condições.
Isso parece ter o menor número de desvantagens, exceto a falta de impor um número fixo de condições para cada par. No entanto, faz sentido criar um novo ID que não identifique nada além dos existentes?
Opção 4 (3b)
Basicamente, o mesmo que a Opção 3, mas sem a criação do campo ID adicional. Isso é feito colocando os dois IDs originais na nova tabela de junção, para que ele contenha x_id
e y_id
campos, em vez de xy_id
.
Uma vantagem adicional desse formulário é que ele não altera as tabelas existentes (embora elas ainda não estejam em produção). No entanto, basicamente duplica uma tabela inteira várias vezes (ou parece que é assim mesmo) e também não parece ideal.
Sumário
Meu sentimento é que as opções 3 e 4 são semelhantes o suficiente para que eu pudesse ir com qualquer uma delas. Eu provavelmente teria agora, se não fosse a exigência de um número pequeno e fixo de links para propriedades, o que faz a Opção 1 parecer mais razoável do que seria. Com base em alguns testes muito limitados, a adição de uma DISTINCT
cláusula às minhas consultas não parece afetar o desempenho nessa situação, mas não tenho certeza de que a Opção 2 represente a situação e as demais, devido à duplicação inerente causada pela colocação os mesmos pares (X, Y) em várias linhas da tabela de links.
É uma dessas opções o meu melhor caminho a seguir ou há outra estrutura que devo considerar?
DISTINCT
cláusula, eu estava pensando em uma consulta como a que está no final do nº 2, que vincula x
e y
através, xyc
mas não se refere a c
... Então, se eu tiver (x_id, y_id, c_id)
restrições UNIQUE
com linhas (1,1,1)
e (1,1,2)
, então SELECT x.id, y.id FROM x JOIN xyc JOIN y
, retornarei duas idênticas linhas (1,1)
, e (1,1)
.