Zalecany projekt bazy danych SQL dla tagów lub tagów [zamknięty]
Słyszałem o kilku sposobach implementacji tagowania; używanie tabeli mapowania pomiędzy TagID i ItemID (ma sens, ale czy jest skalowany?), dodanie stałej liczby możliwych kolumn TagID do ItemID( wydaje się złym pomysłem), utrzymanie tagów w kolumnie tekstowej oddzielonej przecinkami (brzmi szalenie, ale może działać). Słyszałem nawet, że ktoś poleca rzadką matrycę, ale w jaki sposób nazwy tagów rosną wdzięcznie?
Czy brakuje mi najlepszych praktyk dla tagów?
6 answers
Trzy tabele (jedna do przechowywania wszystkich elementów, jedna do wszystkich znaczników i jedna do relacji między nimi), odpowiednio zindeksowane, z ustawionymi kluczami obcymi działającymi na odpowiedniej bazie danych, powinny działać dobrze i odpowiednio skalować.
Table: Item
Columns: ItemID, Title, Content
Table: Tag
Columns: TagID, Title
Table: ItemTag
Columns: ItemID, TagID
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 19:22:44
Normalnie zgodziłbym się z Yaakovem Ellisem, ale w tym szczególnym przypadku jest inne realne rozwiązanie:
Użyj dwóch tabel:
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
To ma kilka głównych zalet:
Po pierwsze sprawia, że rozwój jest znacznie prostszy: w trójstopniowym rozwiązaniu insert I update item
musisz wyszukać tabelę Tag
, aby sprawdzić, czy są już wpisy. Następnie musisz dołączyć do nich nowe. To nie jest trywialne zadanie.
Potem sprawia, że zapytania są prostsze (i być może szybciej). Istnieją trzy główne zapytania bazy danych, które wykonasz: Wyjście wszystkich {[9] } dla jednego Item
, narysowanie chmury znaczników i zaznaczenie wszystkich elementów dla jednego tytułu znacznika.
Wszystkie tagi dla jednego elementu:
3-Tabela:
SELECT Tag.Title
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
WHERE ItemTag.ItemID = :id
2-Tabela:
SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id
Tag-Cloud:
3-Tabela:
SELECT Tag.Title, count(*)
FROM Tag
JOIN ItemTag ON Tag.TagID = ItemTag.TagID
GROUP BY Tag.Title
2-Tabela:
SELECT Tag.Title, count(*)
FROM Tag
GROUP BY Tag.Title
Artykułów dla jednego tagu:
3-Tabela:
SELECT Item.*
FROM Item
JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
JOIN Tag ON ItemTag.TagID = Tag.TagID
WHERE Tag.Title = :title
2-Tabela:
SELECT Item.*
FROM Item
JOIN Tag ON Item.ItemID = Tag.ItemID
WHERE Tag.Title = :title
Ale są pewne wady: może to zająć więcej miejsca w bazie danych (co może prowadzić do większej ilości operacji na dysku, która jest wolniejsza) i nie jest znormalizowana, co może prowadzić do niespójności.
Argument size 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ł tagu jest znacznie szybsze w małej tabeli, która zawiera każdy tag tylko raz i to z pewnością jest prawdą. Ale biorąc w zwróć uwagę na oszczędności za to, że nie musisz dołączać, a fakt, że możesz zbudować na nich dobry indeks, może łatwo to zrekompensować. To oczywiście zależy w dużej mierze od wielkości bazy danych, której używasz.
Argument niespójności jest również trochę dyskusyjny. Tagi są wolnymi polami tekstowymi i nie ma oczekiwanej operacji takiej jak 'Zmień nazwę wszystkich tagów" foo " na "bar"'.
Więc tldr: wybrałbym rozwiązanie dwustawne. (W rzeczywistości zamierzam. Znalazłem ten artykuł, aby sprawdzić, czy są ważne argumenty przeciw.)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-12-04 16:49:34
Jeśli używasz bazy danych obsługującej map-reduce, jak couchdb, przechowywanie znaczników w polu tekstowym lub polu listy jest rzeczywiście najlepszym sposobem. Przykład:
tagcloud: {
map: function(doc){
for(tag in doc.tags){
emit(doc.tags[tag],1)
}
}
reduce: function(keys,values){
return values.length
}
}
Uruchomienie tego z group = true spowoduje pogrupowanie wyników według nazwy znacznika, a nawet zwróci liczbę razy, ile ten znacznik został napotkany. Jest bardzo podobny do zliczania wystąpień słowa w tekście .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-20 04:47:45
Użyj jednej sformatowanej kolumny tekstowej[1] do przechowywania znaczników i użyj zdolnej Wyszukiwarki pełnotekstowej do indeksowania tego. W przeciwnym razie napotkasz problemy ze skalowaniem podczas próby implementacji zapytań logicznych.
Jeśli potrzebujesz szczegółów na temat posiadanych tagów, możesz albo śledzić je w tabeli utrzymywanej przyrostowo, albo uruchomić zadanie wsadowe, aby wyodrębnić informacje.
[1] Niektóre RDBMS zapewniają nawet natywny typ tablicy, który może być nawet lepiej dostosowany do pamięci masowej, ponieważ nie wymaga krok parsowania, ale może powodować problemy z wyszukiwaniem pełnego tekstu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-07 11:47:34
Zawsze trzymałem znaczniki w osobnej tabeli, a potem miałem tabelę mapowania. Oczywiście nigdy nie robiłem niczego na naprawdę dużą skalę.
Posiadanie tabeli "tags" i tabeli map sprawia, że generowanie chmur znaczników jest dość trywialne, ponieważ można łatwo połączyć SQL, aby uzyskać listę tagów z licznikami, jak często każdy tag jest używany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-21 19:23:32
Proponuję następujący projekt :
Tabela Pozycji:
Itemid, taglist1, taglist2
będzie to szybkie i łatwe zapisywanie i pobieranie danych na poziomie pozycji.
Równolegle buduj kolejną tabelę: Tagi znacznik nie rób znacznika unikalnym identyfikatorem i jeśli zabraknie miejsca w 2 kolumnie, która zawiera powiedzmy 100 elementów, utwórz kolejny wiersz.
Teraz podczas wyszukiwania elementów dla tagu będzie super szybko.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-28 09:51:15