Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Como armazenar relacionamentos bidirecionais em um RDBMS como o MySQL?


Veja como essas duas abordagens serão representadas fisicamente no banco de dados:



Vamos analisar as duas abordagens...

Abordagem 1 (ambas as direções armazenadas na tabela):
  • PRO:consultas mais simples.
  • CON:Os dados podem ser corrompidos ao inserir/atualizar/excluir somente uma direção.
  • MINOR PRO:não requer restrições adicionais para garantir que uma amizade não possa ser duplicada.
  • Análise adicional necessária:
    1. TIE:um índice capas ambas as direções, então você não precisa de um índice secundário.
    2. TIE:requisitos de armazenamento.
    3. TIE:Desempenho.

Abordagem 2 (apenas uma direção armazenada na tabela):
  • CON:consultas mais complicadas.
  • PRO:Não é possível corromper os dados esquecendo de lidar com a direção oposta, pois não há direção oposta .
  • MINOR CON:Requer CHECK(UID < FriendID) , então uma mesma amizade nunca pode ser representada de duas maneiras diferentes, e a chave em (UID, FriendID) pode fazer seu trabalho.
  • Análise adicional necessária:
    1. TIE:Dois índices são necessários para cobrir ambas as direções de consulta (índice composto em {UID, FriendID} e índice composto em {FriendID, UID} ).
    2. TIE:requisitos de armazenamento.
    3. TIE:Desempenho.

O ponto 1 é de especial interesse. MySQL/InnoDB sempre clusters dados e índices secundários podem ser caros em tabelas clusterizadas (consulte "Desvantagens do clustering" em este artigo ), então pode parecer que o índice secundário na abordagem 2 consumiria todas as vantagens de menos linhas. No entanto , o índice secundário contém exatamente os mesmos campos que o primário (apenas na ordem oposta), portanto, não há sobrecarga de armazenamento nesse caso específico. Também não há ponteiro para o heap da tabela (já que não há heap da tabela), portanto, provavelmente é ainda mais barato em termos de armazenamento do que um índice normal baseado em heap. E supondo que a consulta seja coberta pelo índice, também não haverá uma pesquisa dupla normalmente associada a um índice secundário em uma tabela clusterizada. Então, isso é basicamente um empate (nem a abordagem 1 nem a abordagem 2 tem vantagem significativa).

O ponto 2 está relacionado ao ponto 1:não importa se teremos uma B-Tree de N valores ou duas B-Trees, cada uma com valores N/2. Portanto, isso também é um empate:ambas as abordagens usarão aproximadamente a mesma quantidade de armazenamento.

O mesmo raciocínio se aplica ao ponto 3 :se procuramos uma B-Tree maior ou 2 menores, não faz muita diferença, então isso também é um empate.

Portanto, pela robustez, e apesar das consultas um pouco mais feias e da necessidade de CHECK adicionais , eu iria com a abordagem 2.