Wenn A
ein Freund von ist B
, sollte ich dann beide Werte speichern AB
und BA
, oder einer ist genug? Was sind die Vor- und Nachteile beider Methoden.
Hier ist meine Beobachtung:
- Wenn ich beide behalte, muss ich beide aktualisieren, wenn ich eine Anfrage von einem Freund erhalte.
- Wenn ich nicht beide behalte, fand ich es schwierig,
JOIN
mit dieser Tabelle mehrere zu machen .
Derzeit halte ich die Beziehung in eine Richtung.
Was soll ich in diesem Fall tun? Irgendein Rat?
mysql
relational-theory
Chan
quelle
quelle
mysql
was in der Amazon Cloud gespeichert ist.Antworten:
Ich würde AB und BA speichern. Eine Freundschaft ist wirklich eine wechselseitige Beziehung, jede Entität ist mit einer anderen verbunden. Auch wenn wir die "Freundschaft" intuitiv als ein Bindeglied zwischen zwei Personen betrachten, ähnelt sie aus relationaler Sicht eher "A hat einen Freund B" und "B hat einen Freund A". Zwei Beziehungen, zwei Aufzeichnungen.
quelle
Wenn Freundschaft symmetrisch sein soll (dh es ist nicht möglich
A
, Freunde zu sein,B
aber nicht umgekehrt), würde ich die Einwegbeziehung nur mit einer Check-Einschränkung speichern, um sicherzustellen, dass jede Beziehung nur in eine Richtung dargestellt werden kann.Außerdem würde ich die Ersatz-ID weglassen und stattdessen eine zusammengesetzte PK haben (und möglicherweise einen zusammengesetzten eindeutigen Index auch für die umgekehrten Spalten).
Sie sagen nicht die Abfragen, die dies schwierig macht, aber Sie können immer eine Ansicht erstellen
quelle
UNIQUE
, umINSERT
s nicht unnötig und überflüssig zu belasten ? Da wir habenPRIMARY KEY (a,b)
und da ein PK istUNIQUE
, ist das UmkehrenKEY (b,a)
auchUNIQUE
egal was.Unter der Annahme, dass eine "Freundschaft" immer wechselseitig ist, würde ich wahrscheinlich damit umgehen.
Das Ergebnis ist, dass Sie es von einer Viele-zu-Viele-Verbindung von "Person" zu "Person", zu einer Viele-zu-Viele-Verbindung von "Person" zu "Freundschaft" ändern. Dies vereinfacht Verknüpfungen und Einschränkungen, hat jedoch den Nebeneffekt, dass mehr als zwei Personen eine einzige "Freundschaft" eingehen können (obwohl die zusätzliche Flexibilität möglicherweise ein potenzieller Vorteil wäre).
quelle
Möglicherweise müssen Sie Indizes für Freundschaften definieren, anstatt die Anzahl der Zeilen zu verdoppeln:
Auf diese Weise verdoppeln Sie den Speicher für Indizes, jedoch nicht für die Tabellendaten. Infolgedessen sollte dies eine Einsparung von 25% des Speicherplatzes bedeuten. Der MySQL Query Optimizer wählt nur die Ausführung von Indexbereichs-Scans aus, weshalb das Konzept der Indexabdeckung hier gut funktioniert.
Hier sind ein paar nette Links zu den Titelindizes:
VORBEHALT
Wenn Freundschaft nicht auf Gegenseitigkeit beruht, haben Sie die Grundlage für eine andere Art von Beziehung: FOLLOWER
Wenn friend_to kein Freund von friend_of ist, können Sie diese Beziehung einfach aus der Tabelle streichen.
Wenn Sie Beziehungen für alle Typen definieren möchten, unabhängig davon, ob sie wechselseitig sind oder nicht, können Sie möglicherweise das folgende Tabellenlayout verwenden:
In der Beziehungstabelle können Sie die Beziehungen so anordnen, dass sie Folgendes enthalten:
Dies sollte für alle Beziehungen robuster sein, unabhängig davon, ob die Beziehung wechselseitig ist oder nicht.
quelle
Wenn Sie in der Anwendung steuern können, dass die ID von A immer niedriger als die ID von B ist (vorbestellen der IDs der A- und B-Elemente), können Sie das Fragen ohne ODER nutzen (wählen Sie, wo id_A = a UND id_B = b, anstatt zu fragen (id_A = a UND id_B = b) ODER (id_A = b UND id_B = a)) und behalten Sie auch die Hälfte der Datensätze bei, die Sie mit den Annäherungen des anderen benötigen. Dann sollten Sie ein anderes Feld verwenden, um den Status der Beziehung beizubehalten (sind Freunde, a-angefragt-an-b, b-angefragt-an-a, Exfreunde-a, Exfreunde-b), und fertig.
Auf diese Weise habe ich mein Freundschaftssystem verwaltet. Dies vereinfacht das System und belegt die Hälfte der Zeilen, die Sie für andere Systeme benötigen. Nur A entspricht dem niedrigeren ID-Wert im Code.
quelle