Используя SO в качестве примера, что является наиболее разумным способом управления тегами, если вы ожидаете, что они будут часто меняться?
Способ 1: Серьезно денормализованный (с разделителями-запятыми)
table posts +--------+-----------------+ | postId | tags | +--------+-----------------+ | 1 | c++,search,code |
Здесь теги разделены запятой.
Плюсы. Теги извлекаются сразу с помощью одного запроса select
. Обновление тегов прост. Легко и дешево обновить.
Минусы: дополнительный синтаксический анализ при поиске тегов, трудно подсчитать, сколько сообщений использует теги.
(альтернативно, если ограничено чем-то вроде 5 тегов)
table posts +--------+-------+-------+-------+-------+-------+ | postId | tag_1 | tag_2 | tag_3 | tag_4 | tag_5 | +--------+-------+-------+-------+-------+-------+ | 1 | c++ |search | code | | |
Способ 2: "Немного нормализованный" (отдельная таблица, без пересечения)
table posts +--------+-------------------+ | postId | title | +--------+-------------------+ | 1 | How do u tag? | table taggings +--------+---------+ | postId | tagName | +--------+---------+ | 1 | C++ | | 1 | search |
Плюсы. Легко видеть количество тегов (count(*) from taggings where tagName='C++'
).
Минусы: tagName будет повторяться много раз.
Путь 3: Холодный малыш (нормализованный с таблицей пересечений)
table posts +--------+---------------------------------------+ | postId | title | +--------+---------------------------------------+ | 1 | Why is a raven like a writing desk? | table tags +--------+---------+ | tagId | tagName | +--------+---------+ | 1 | C++ | | 2 | search | | 3 | foofle | table taggings +--------+---------+ | postId | tagId | +--------+---------+ | 1 | 1 | | 1 | 2 | | 1 | 3 |
Профи:
- Нет повторяющихся имен тегов.
- Вам понравятся больше девушек.
Минусы: дороже менять теги, чем путь №1.