.note | Tag Systems

Ну и что, скажите, сложного в том, чтобы вешать в своей системе на все единицы контента N тегов, и после делать по этим тегам выборку с системой релевантности и важности связей? Да ничего в этом сложного нет, ибо это типовая задачка по проектированию БД из 10го класса! Что? Вы всё ещё кипятите? Ну тогда я расставлю быстренько все галочки :)

Итак, задача: Иметь возможность маркировать любой контент в системе «ключевыми словами», по которым позже делать выборку для получения списка данных, маркированых точно такими же ключсловами.

Решение: По сути, сама система тегов — это три дополнительных таблицы в СУБД, на которые уже завязан весь остальной контент. Примерно вот так (голубым помечены сторонние сущности системы, их может быть сколько угодно):

[image]

Дальше всё просто, в таблице 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 или любой уважающей себя СУБД).

Top

Слова: databases, mysql

Комментарии Отключены
Комментарий Удалён
Комментарий Удалён

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 [ ссылка ]