Słyszałem o kilku sposobach implementacji tagowania; używając tabeli odwzorowań między TagID a ItemID (ma to dla mnie sens, ale czy skaluje się?), dodając stałą liczbę możliwych kolumn TagID do ItemID (wydaje się to zły pomysł), Utrzymując znaczniki w kolumnie tekstowej oddzielonej przecinkami (dźwięki szalony, ale może działać). Słyszałem nawet, że ktoś poleca rzadką matrycę, ale w jaki sposób nazwy tagów rosną z wdziękiem?
Czy brakuje mi najlepszej praktyki dotyczącej tagów?
sql
database-design
tags
data-modeling
tagging
dlamblin
źródło
źródło
Odpowiedzi:
Trzy tabele (jedna do przechowywania wszystkich elementów, jedna do wszystkich tagów i jedna do relacji między nimi), odpowiednio zindeksowane, z zestawem kluczy obcych działającym w odpowiedniej bazie danych, powinny działać dobrze i poprawnie skalować.
źródło
Zwykle zgodziłbym się z Yaakovem Ellisem, ale w tym szczególnym przypadku istnieje inne realne rozwiązanie:
Użyj dwóch tabel:
Ma to kilka głównych zalet:
Po pierwsze, programowanie jest znacznie prostsze: w rozwiązaniu z trzema tabelami do wstawiania i aktualizacji
item
musisz sprawdzićTag
tabelę, aby sprawdzić, czy są już wpisy. Następnie musisz dołączyć do nich z nowymi. To nie jest trywialne zadanie.Dzięki temu zapytania stają się prostsze (a być może szybsze). Istnieją trzy główne zapytania do bazy danych, które należy wykonać: Wyprowadź wszystko
Tags
dla jednegoItem
, narysuj chmurkę tagów i wybierz wszystkie elementy dla jednego tytułu tagu.Wszystkie tagi dla jednej pozycji:
3-stół:
2-stół:
Tag-Cloud:
3-stół:
2-stół:
Produkty dla jednego tagu:
3-stół:
2-stół:
Ale są też pewne wady: może zająć więcej miejsca w bazie danych (co może prowadzić do większej liczby operacji na dysku, co jest wolniejsze) i nie jest znormalizowany, co może prowadzić do niespójności.
Argument wielkości nie jest tak silny, ponieważ sama natura tagów polega na tym, że zwykle są one dość małe, więc wzrost rozmiaru nie jest duży. Można argumentować, że zapytanie o tytuł znacznika jest znacznie szybsze w małej tabeli, która zawiera każdy znacznik tylko raz, a to z pewnością jest prawdą. Ale biorąc pod uwagę oszczędności wynikające z rezygnacji z przyłączenia się oraz fakt, że można na nich zbudować dobry indeks, można to łatwo zrekompensować. Zależy to oczywiście w dużej mierze od wielkości używanej bazy danych.
Argument o niekonsekwencji jest również trochę dyskusyjny. Tagi są polami tekstowymi i nie ma oczekiwanej operacji, takiej jak „zmień nazwę wszystkich tagów„ foo ”na„ bar ”.
Więc tldr: wybrałbym rozwiązanie z dwoma stołami. (W rzeczywistości zamierzam. Znalazłem ten artykuł, aby sprawdzić, czy istnieją uzasadnione argumenty przeciwko niemu.)
źródło
Jeśli korzystasz z bazy danych obsługującej redukcję mapy, takiej jak couchdb, przechowywanie znaczników w polu tekstowym lub polu listy jest rzeczywiście najlepszym sposobem. Przykład:
Uruchomienie tego z group = true grupuje wyniki według nazwy znacznika, a nawet zwraca liczbę przypadków napotkania znacznika. Jest to bardzo podobne do liczenia występowania słowa w tekście .
źródło
Użyj pojedynczej sformatowanej kolumny tekstowej [1] do przechowywania znaczników i użyj zdolnej wyszukiwarki pełnotekstowej do jej indeksowania. W przeciwnym razie napotkasz problemy ze skalowaniem podczas próby implementacji zapytań boolowskich.
Jeśli potrzebujesz szczegółowych informacji o posiadanych tagach, możesz śledzić je w przyrostowo utrzymywanej tabeli lub uruchomić zadanie wsadowe w celu wyodrębnienia informacji.
[1] Niektóre RDBMS zapewniają nawet natywny typ macierzy, który może być jeszcze lepiej przystosowany do przechowywania, ponieważ nie wymaga etapu analizy, ale może powodować problemy z wyszukiwaniem pełnotekstowym.
źródło
Zawsze trzymałem tagi w osobnej tabeli, a potem miałem tabelę mapowania. Oczywiście, nigdy nie zrobiłem nic na naprawdę dużą skalę.
Posiadanie tabeli „znaczników” i tabeli map sprawia, że generowanie chmur znaczników jest bardzo proste, ponieważ można łatwo łączyć SQL, aby uzyskać listę znaczników z licznikiem częstotliwości używania każdego znacznika.
źródło
Sugerowałbym następujący projekt: Tabela przedmiotów: Itemid, taglist1, taglist2
to będzie szybkie i ułatwi zapisywanie i pobieranie danych na poziomie przedmiotu.
Równolegle buduj inną tabelę: Tag tagów nie powoduje, że tag jest unikalnym identyfikatorem, a jeśli zabraknie miejsca w drugiej kolumnie, która zawiera, powiedzmy 100 elementów tworzy kolejny wiersz.
Teraz podczas wyszukiwania elementów dla tagu będzie super szybko.
źródło