Jeśli A
jesteś przyjacielem B
, to czy powinienem przechowywać obie wartości AB
i BA
czy jedna wystarczy? Jakie są zalety i wady obu metod.
Oto moja obserwacja:
- Jeśli zachowam oba, muszę je zaktualizować po otrzymaniu prośby od znajomego.
- Jeśli nie zachowam obu, wtedy trudno mi było zrobić wiele
JOIN
przy tej tabeli.
Obecnie utrzymuję związek w jedną stronę.
Więc co powinienem zrobić w tym przypadku? Jakakolwiek rada?
mysql
relational-theory
Chan
źródło
źródło
mysql
które są przechowywane w chmurze Amazon.Odpowiedzi:
Przechowałbym AB i BA. Przyjaźń jest tak naprawdę dwustronnym związkiem, każdy byt jest powiązany z innym. Chociaż intuicyjnie myślimy o „przyjaźni” jako o połączeniu między dwojgiem ludzi, z relacyjnego punktu widzenia bardziej przypomina „A ma przyjaciela B” i „B ma przyjaciela A”. Dwie relacje, dwie rekordy.
źródło
Jeśli przyjaźń ma być symetryczna (tj. Nie jest możliwe,
A
aby być przyjaciółmi,B
ale nie odwrotnie), zapisałbym tylko relację jednokierunkową z ograniczeniem sprawdzania, aby każda relacja mogła być reprezentowana tylko w jeden sposób.Również porzuciłbym identyfikator zastępczy i zamiast tego miałbym złożony PK (i prawdopodobnie złożony unikalny indeks również na odwróconych kolumnach).
Nie podajesz zapytań, które to utrudniają, ale zawsze możesz utworzyć Widok
źródło
UNIQUE
, aby nie nakładać zbędnego i zbędnego dodatkowego obciążenia naINSERT
s? Ponieważ mamy,PRIMARY KEY (a,b)
a ponieważ PK jestUNIQUE
, odwrotnośćKEY (b,a)
równieżUNIQUE
nie ma znaczenia.Zakładając, że „przyjaźń” jest zawsze dwustronna / wzajemna, prawdopodobnie poradziłbym sobie z czymś takim.
W rezultacie zmieniasz to z łączenia wielu w wielu z „osoby” w „osobę”, w łączenia wielu w wielu z „osoby” w „przyjaźń”. Uprości to połączenia i ograniczenia, ale efektem ubocznym jest umożliwienie więcej niż dwóm osobom w jednej „przyjaźni” (choć może dodatkowa elastyczność byłaby potencjalną zaletą).
źródło
Może być konieczne zdefiniowanie indeksów wokół przyjaźni zamiast podwojenia liczby wierszy:
W ten sposób podwajasz pamięć dla indeksów, ale nie dla danych tabeli. W rezultacie powinno to stanowić 25% oszczędności miejsca na dysku. Optymalizator zapytań MySQL wybierze tylko skanowanie zakresu indeksów, dlatego koncepcja pokrywania indeksów działa tutaj dobrze.
Oto kilka ciekawych linków na temat indeksów obejmujących:
CAVEAT
Jeśli przyjaźń nie jest wzajemna, masz podstawę do innego rodzaju relacji: OBSERWUJ
Jeśli friend_to nie jest przyjacielem friend_of, możesz po prostu pozostawić ten związek poza tabelą.
Jeśli chcesz zdefiniować relacje dla wszystkich typów, niezależnie od tego, czy są one wzajemne, czy nie, prawdopodobnie możesz użyć następującego układu tabeli:
W tabeli relacji można ułożyć relacje w następujący sposób:
Powinno to być bardziej niezawodne dla wszystkich relacji, niezależnie od tego, czy związek jest wzajemny, czy nie.
źródło
Jeśli możesz kontrolować w aplikacji, że identyfikator A jest zawsze niższy niż identyfikator B (zamów w przedsprzedaży identyfikatory elementów A, B), możesz skorzystać z pytania bez OR (wybierz gdzie id_A = AND AND id_B = b, zamiast pytać (id_A = a AND id_B = b) OR (id_A = b AND id_B = a)), a także zachowaj połowę rekordów, których potrzebujesz z przybliżeniami drugiej osoby. Następnie powinieneś użyć innego pola, aby utrzymać stan relacji (są-przyjaciółmi, a-prosi-do-b, b-prosi-do-a, exfriends-a, exfriends-b) i gotowe.
W ten sposób zarządzałem moim systemem przyjaźni, a to upraszcza system i wykorzystuje połowę wierszy, których potrzebujesz w innych systemach, mówiąc tylko, że A jest równe niższej wartości id w kodzie.
źródło