Базы данных « Как правильно хранить теги контента в базе?

Есть контент, его можно помечать тегами. Потом будет возможность поиска по тегам, отбора по тегам и тп.

Как лучше хранить теги в базе? Какие модели тегирования вы знаете и какая схема, по вашему мнению, лучшая?

1 ответов


Ну самое очевидное это использование промежуточной между контентом и тэгами таблицы:


CREATE TABLE "content" (
  "id" int NOT NULL,
  "content" text,
  PRIMARY KEY  ("id")
);

CREATE TABLE "tag" (
  "id" int NOT NULL,
  "name" varchar(100) NOT NULL,
  PRIMARY KEY  ("id")
);

CREATE TABLE "content_tag" (
  "id_content" int NOT NULL,
  "id_tag" int NOT NULL DEFAULT '0',
  UNIQUE KEY "id_content_tag" ("id_content","id_tag"),
  CONSTRAINT "content_tag_ibfk_1" FOREIGN KEY ("id_content") REFERENCES "content" ("id"),
  CONSTRAINT "content_tag_ibfk_2" FOREIGN KEY ("id_tag") REFERENCES "tag" ("id")
);
 

Я знаю три основных способа.

1. Первый что описал LighteR

2. Хранение тегов для каждого поста отдельно без промежуточной таблицы. В данном случае теги могут повторяться сколько-угодно раз, тогда как в первом тег записывается один раз и повторяется в промежуточной таблице content_tag.



CREATE TABLE "content" (
  "id" int NOT NULL,
  "content" text,
  PRIMARY KEY  ("id")
);

CREATE TABLE "content_tag" (
  "id_content" int NOT NULL,
  "tag_value" varchar(128) NOT NULL,
  UNIQUE KEY "id_content_tag" ("id_content","tag_value"),
  CONSTRAINT "content_tag_ibfk_1" FOREIGN KEY ("id_content") REFERENCES "content" ("id"),
);
 

3. Хранение тегов как текст вместе с самим контентом.


CREATE TABLE "content" (
  "id" int NOT NULL,
  "content" text,
  "tags" varchar(512) NOT NULL,
  PRIMARY KEY  ("id")
);
 


Каждый способ хорош в определенной ситуации. Самый гибкий способ первый.



Вы забыли тут указать, что первый вариант с внешними ключами работает только если таблица на движке InnoDB, а InnoDB имеет свои недостатки, в частности, медленнее происходит выборка (как раз для тегов это важно) и апдейт записи. Возможно производительнее будет вариант без внешних ключей, а при добавлении, изменении делать проверочный запрос. Поправьте меня если вы думаете, что есть более производительная схема.


Вот статья на хабре - очень интересная. там описываются плюсы и минусы различных реализаций