Si A
est un ami de B
, alors devrais-je stocker les deux valeurs AB
et BA
, ou est-ce suffisant? Quels sont les avantages et les inconvénients des deux méthodes.
Voici mon observation:
- Si je garde les deux, je dois les mettre à jour lorsque je reçois une demande d'un ami.
- Si je ne garde pas les deux, alors j'ai eu du mal à faire plusieurs
JOIN
avec cette table.
Actuellement, je garde la relation dans un sens.
Alors, que dois-je faire dans ce cas? Aucun conseil?
mysql
ce qui est stocké dans le nuage Amazon.Réponses:
Je voudrais stocker AB et BA. Une amitié est vraiment une relation à double sens, chaque entité est liée à une autre. Même si, intuitivement, nous pensons que "l'amitié" est un lien entre deux personnes, d'un point de vue relationnel, cela ressemble plus à "A a un ami B" et "B a un ami A". Deux relations, deux enregistrements.
la source
Si l’amitié est censée être symétrique (c’est-à-dire qu’il n’est pas possible
A
d’être amiB
mais pas l’inverse), je stockerais simplement la relation unidirectionnelle avec une contrainte de vérification garantissant que chaque relation ne peut être représentée que dans un seul sens.De plus, j’aurais abandonné l’identificateur de substitution et obtenu un PK composite (et éventuellement un index unique composite également sur les colonnes inversées).
Vous ne dites pas les requêtes que cela rend difficile mais vous pouvez toujours créer une vue
la source
UNIQUE
pour ne pas imposer une charge supplémentaire inutile et redondante àINSERT
s? Depuis que nous avonsPRIMARY KEY (a,b)
et depuis qu'une PC estUNIQUE
, l'inverseKEY (b,a)
est aussiUNIQUE
n'importe quoi.En supposant qu'une "amitié" soit toujours bidirectionnelle / mutuelle, je le prendrais probablement comme ceci.
Le résultat est que vous le changez de plusieurs à plusieurs, de "personne" à "personne", à une liaison de plusieurs à plusieurs, de "personne" à "amitié". Cela simplifiera les jointures et les contraintes, mais aura pour effet secondaire de permettre à plus de deux personnes de former une seule "amitié" (bien que la flexibilité supplémentaire puisse constituer un avantage potentiel).
la source
Vous devrez peut-être définir des index autour des amitiés au lieu de doubler le nombre de lignes:
De cette façon, vous doublez le stockage pour les index mais pas pour les données de la table. En conséquence, cela devrait représenter une économie de 25% sur l’espace disque. L'optimiseur de requêtes MySQL choisit uniquement d'effectuer des analyses de plages d'index. C'est pourquoi le concept de couverture d'index fonctionne bien ici.
Voici quelques liens intéressants sur les index de couverture:
CAVEAT
Si l'amitié n'est pas réciproque, vous avez la base d'un autre type de relation: SUIVEZ
Si friend_to n'est pas un ami de friend_of, vous pouvez simplement laisser cette relation en dehors de la table.
Si vous souhaitez définir des relations pour tous les types, qu'elles soient mutuelles ou non, vous pouvez probablement utiliser la disposition de tableau suivante:
À partir de la table de relations, vous pouvez organiser les relations de manière à inclure les éléments suivants:
Cela devrait être plus robuste pour toutes les relations, qu'elles soient mutuelles ou non.
la source
Si vous pouvez contrôler dans l’application que l’id de A est toujours inférieur à celui de B (pré-commandez les identifiants des éléments A, B), vous pouvez utiliser le moyen de demander sans OR (sélectionnez où id_A = a AND id_B = b, au lieu de demander (id_A = a AND id_B = b) OR (id_A = b AND id_B = a)), et conservez également la moitié des enregistrements dont vous aurez besoin avec les approximations de l'autre. Ensuite, vous devez utiliser un autre champ pour maintenir l'état de la relation (êtes-amis, a-sollicité-à-b, b-sollicité-à-a, exfriends-a, exfriends-b), et vous avez terminé.
C’est ainsi que j’ai géré mon système d’amitié, ce qui simplifie le système et utilise la moitié des rangées dont vous aurez besoin avec d’autres systèmes, en indiquant simplement que A est égal à la valeur inférieure de code dans le code.
la source