Se A
é amigo B
, devo guardar os dois valores AB
e BA
, ou um é suficiente? Quais são as vantagens e desvantagens de ambos os métodos.
Aqui está minha observação:
- Se eu mantiver os dois, preciso atualizá-los quando receber uma solicitação de um amigo.
- Se eu não mantiver os dois, será difícil ter que fazer vários
JOIN
com esta tabela.
Atualmente, mantenho o relacionamento de uma maneira.
Então, o que devo fazer neste caso? Algum conselho?
mysql
relational-theory
Chan
fonte
fonte
mysql
qual está armazenado na nuvem da Amazon.Respostas:
Eu armazenaria AB e BA. Uma amizade é realmente um relacionamento de mão dupla, cada entidade está ligada a outra. Embora intuitivamente pensemos na "amizade" como um elo entre duas pessoas, do ponto de vista relacional, é mais como "A tem um amigo B" e "B tem um amigo A". Dois relacionamentos, dois registros.
fonte
Se a amizade tiver a intenção de ser simétrica (ou seja, não é possível
A
ser amiga,B
mas não vice-versa), eu armazenaria apenas o relacionamento unidirecional com uma restrição de verificação, garantindo que cada relacionamento possa ser representado apenas de uma maneira.Também abandonaria o ID substituto e, em vez disso, teria uma PK composta (e possivelmente um índice exclusivo composto também nas colunas invertidas).
Você não diz as consultas que dificultam, mas sempre pode criar uma Visualização
fonte
UNIQUE
, a fim de não sobrecarregar desnecessariamente e redundantementeINSERT
s? Como temosPRIMARY KEY (a,b)
e como é um PKUNIQUE
, o inversoKEY (b,a)
tambémUNIQUE
não importa o quê.Supondo que uma "amizade" seja sempre bidirecional / mútua, eu provavelmente lidaria com algo assim.
O resultado é que você muda de uma associação muitos para muitos de "pessoa" para "pessoa", para uma associação muitos para muitos de "pessoa" para "amizade". Isso simplificará junções e restrições, mas tem o efeito colateral de permitir mais de duas pessoas em uma única "amizade" (embora talvez a flexibilidade adicional seja uma vantagem potencial).
fonte
Pode ser necessário definir índices em torno de amizades, em vez de dobrar o número de linhas:
Dessa forma, você duplica o armazenamento para índices, mas não para os dados da tabela. Como resultado, isso deve economizar 25% no espaço em disco. O MySQL Query Optimizer escolherá executar apenas varreduras de intervalo de índice, razão pela qual o conceito de cobertura de índices funciona bem aqui.
Aqui estão alguns links interessantes sobre Cobertura de índices:
EMBARGO
Se a amizade não é mútua, você tem a base para outro tipo de relacionamento: SEGUINTE
Se friend_to não for amigo de friend_of, você pode simplesmente deixar esse relacionamento fora da tabela.
Se você deseja definir relacionamentos para todos os tipos, sejam eles mútuos ou não, provavelmente você pode usar o seguinte layout de tabela:
Na tabela de relações, você pode organizar os relacionamentos para incluir o seguinte:
Isso deve ser mais robusto para todos os relacionamentos, seja o relacionamento mútuo ou não.
fonte
Se você pode controlar dentro do aplicativo que o ID de A é sempre menor que o ID de B (pré-ordena os IDs dos elementos A, B), você pode pedir sem um OR (selecione onde id_A = a AND id_B = b, em vez de perguntar (id_A = a AND id_B = b) OR (id_A = b AND id_B = a)), e também mantenha metade dos registros necessários com as aproximações dos outros. Em seguida, você deve usar outro campo para manter o estado do relacionamento (são-amigos, a-solicitado-a-b, b-solicitado-a-a, ex-amigos-a, ex-amigos-b) e pronto.
Esta é a maneira como eu gerenciei meu sistema de amizade, e isso simplifica o sistema e usa metade das linhas que você precisará com outros sistemas, apenas dizendo que A é igual ao menor valor de ID no código.
fonte