Який найефективніший спосіб зберігання тегів у базі даних?


138

Я впроваджую на своєму веб-сайті систему тегів, подібну до однієї стаціонарної передачі, моє питання - який найефективніший спосіб зберігати теги, щоб їх можна було шукати та фільтрувати?

Моя ідея така:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

Це занадто повільно? Чи є кращий спосіб?


2
Раніше запитав: stackoverflow.com/questions/20856 / ...
DrBloodmoney

1
Станом на 2016 рік використовуйте Solr або Elasticsearch
Чарльз Л.

Відповіді:


189

На одному елементі буде багато тегів. І один тег буде належати багатьом предметам. Це означає для мене, що вам цілком можливо знадобиться посередницька таблиця, щоб подолати перешкоду «багато-багато».

Щось на зразок:

Таблиця:
Стовпці елементів : Item_ID, Item_Title, Content

Таблиця:
Стовпці тегів: Tag_ID, Tag_Title

Таблиця:
Стовпці елементів_теги: Item_ID, Tag_ID

Можливо, ваш веб-додаток шалено популярний і потребує денормалізації в дорозі, але безглуздо забруднювати води занадто рано.



якщо є якась річ, наприклад tagGroup, як з цим поводитися, наприклад, теги згруповані в категорії, наприклад: мови програмування: c #, vb, pearl. ОС: windows7, dos, linux тощо
Громад

4
@Thunder: якщо припустити, що один тег може належати лише одній категорії, я створив би таблицю TagCategory, що складається з категорії_id та імені категорії. Звідти я б додав поле категорії_id до таблиці Теги та здійснив приєднання до цього.
Саймон Шарф

114

Ви повинні прочитати повідомлення в блозі Філіпа Келера про тегування схем бази даних. Він намагається зробити кілька і повідомляє про свої результати, як з точки зору простоти побудови загальних запитів , так і з точки зору продуктивності . Кількість тегів, кількість тегів та кількість тегів на предмет - усі фактори. Повідомлення від 2005 року; З тих пір я не знаю жодних оновлень.


19
Я думаю, що це найкраща відповідь. Він заснований на фактичних тестах та дослідженнях, а не на припущеннях, як більшість інших відповідей.
Крістіан Врабі

4
Здається, посилання у відповіді не працюють. Знайдено копію на vtidter.blogspot.be/2014/02/database-schema-for-tags.html
Крістоф Герреман

8

Насправді я вважаю, що денормалізація таблиці тегів може бути кращим способом вперед, залежно від масштабу.

Таким чином, таблиця тегів просто має tagid, itemid, name tag.

Ви отримаєте повторювані імена тегів, але це робить додавання / видалення / редагування тегів для конкретних елементів МНОГО простішими. Вам не доведеться створювати новий тег, видаляти виділення старого та переділяти новий, ви просто відредагуйте ім'я тегу.

Для відображення списку тегів ви просто використовуєте DISTINCT або GROUP BY, і звичайно ви можете порахувати, скільки разів тег також легко використовується.


4

Якщо ви не заперечуєте проти використання нестандартних матеріалів, у Postgres версії 9.4 і новіших є можливість зберігати запис типу текстового масиву JSON.

Вашою схемою буде:

Table: Items
Columns: Item_ID:int, Title:text, Content:text

Table: Tags
Columns: Item_ID:int, Tag_Title:text[]

Для отримання додаткової інформації дивіться цей чудовий пост Джоша Беркуса: http://www.databasesoup.com/2015/01/tag-all-things.html

Існує більше різноманітних варіантів порівняно ретельно для продуктивності, а запропонований вище найкращий в цілому.


2

Я б запропонував використовувати третю таблицю посередника для зберігання асоціацій тегів <=>, оскільки ми маємо багато-багато відношень між тегами та елементами, тобто один елемент може бути пов'язаний з декількома тегами, а один тег може бути пов'язаний з декількома елементами. HTH, Valve.


1

Ви не можете реально говорити про повільність на основі даних, наданих у запитанні. І я не думаю, що на цій стадії розробки ви навіть не повинні занадто сильно турбуватися про продуктивність. Це називається передчасної оптимізацією .

Однак я б запропонував вам включити стовпчик Tag_ID у таблицю Теги. Зазвичай є хорошою практикою, щоб кожна таблиця мала стовпчик ідентифікатора.


1

Якщо простір буде проблемою, майте теги 3-ї таблиці (Tag_Id, Назва), щоб зберігати текст для тегу, а потім змініть таблицю тегів на (Tag_Id, Item_Id). Ці два значення також повинні забезпечувати унікальний складений первинний ключ.


0

У елементах повинно бути поле "ідентифікатор", а в тегах має бути поле "ідентифікатор" (первинний ключ, кластер).

Потім складіть проміжну таблицю ItemID / TagID і покладіть туди " Ідеальний індекс ".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.