.note | Tag Systems
Ну и что, скажите, сложного в том, чтобы вешать в своей системе на все единицы контента N тегов, и после делать по этим тегам выборку с системой релевантности и важности связей? Да ничего в этом сложного нет, ибо это типовая задачка по проектированию БД из 10го класса! Что? Вы всё ещё кипятите? Ну тогда я расставлю быстренько все галочки :)
Итак, задача: Иметь возможность маркировать любой контент в системе «ключевыми словами», по которым позже делать выборку для получения списка данных, маркированых точно такими же ключсловами.
Решение: По сути, сама система тегов — это три дополнительных таблицы в СУБД, на которые уже завязан весь остальной контент. Примерно вот так (голубым помечены сторонние сущности системы, их может быть сколько угодно):
![[image]](/entry/221/file/tags.jpg)
Дальше всё просто, в таблице content_type_map весь контент системы снабжается дополнительным уникальным ID (для работы с тегами), потому я представляю таблицу примерно вот такого вот вида: CREATE TABLE content_type_map(content_id INT UNSIGNED NOT NULL AUTO INCREMENT, foreign_content_id INT UNSIGNED NOT NULL, content_type ENUM('picture,'article','file'), PRIMARY KEY(content_id), KEY(foreign_content_id));.
Note: Стоит сразу заметить, что я в примерах буду использовать MySQL 4, прекрасно понимая, что эту систему можно многим элегантнее сделать на настоящей СУБД. Но это уже будет песня из другой оперы.
Таблица content_tag_map уже связывает единицы контента с ключевыми словами. В простейшем варианте там будет всего два поля: content_id и tag_id. Однако, для особых извращенцев я бы добавил поле с датой создания записи.
Таблица tags — очень проста: CREATE TABLE tags(tag_id INT UNSIGNED NOT NULL AUTO_INCREMENT, tag VARCHAR(50), UNIQUE(tag), PRIMARY KEY(tag_id));
Вот и вся математика. Далее, можно с этой системой уже устраивать пляски с бубном.
- Простой пример: просто получить все связи от любой единицы контента ко всем другим единицам контента с такими же ключ-словами.
- Более сложный пример: получить все связи с общим «весом» связей
- Ещё более сложный пример: получить все связи с общим «весом» и «актуальностью» связей
- Пример для настоящих извращенцев: нарисовать карту связей контента.
Просто, правда? Конечно, не забываем, что кеш спасёт мир, и записываем все теги в виде сериализированых массивов в кеш-поля в самом контенте (это, кстати, можно сделать с помощью триггеров в MySQL 5 или любой уважающей себя СУБД).

Steel Ice
Сложновато только, если вдруг удаляется что-либо из табличек с контентом чистить табличку tags от уже неиспользованных тегов :)
10.05.2006 // 09:09 [ ссылка ]
Ответ от Автора
отчего же сложно? пишем триггер и не паримся ;)
10.05.2006 // 12:43 [ ссылка ]
kixx
Допустим, у какой-либо единицы контента несколько тегов. Тебе нужно показать все другие единицы контента, с теми же тегами, как и у этой. Т.е. придётся сначала выявлять теги для этой единицы, потом делать запрос "SELECT content_id where tag_id=..." для каждого тега? Или в mysql это можно реализовать проще?
18.05.2006 // 05:07 [ ссылка ]
Ответ от Автора
а что мешает всё одним махом взять?
18.05.2006 // 09:18 [ ссылка ]