Какой самый эффективный способ вставить теги в таблицу - PullRequest
2 голосов
/ 06 января 2010

У меня есть следующие таблицы;

CREATE TABLE IF NOT EXISTS `tags` (
  `tag_id` int(11) NOT NULL auto_increment,
  `tag_text` varchar(255) NOT NULL,
  PRIMARY KEY  (`tag_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;


CREATE TABLE IF NOT EXISTS `users` (
  `user_id` int(11) NOT NULL auto_increment,
  `user_display_name` varchar(128) default NULL,
  PRIMARY KEY  (`user_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=10 ;

CREATE TABLE IF NOT EXISTS `user_post_tag` (
  `upt_id` int(11) NOT NULL auto_increment,
  `upt_user_id` int(11) NOT NULL,
  `upt_post_id` int(11) NOT NULL,
  `upt_tag_id` int(11) NOT NULL,
  PRIMARY KEY  (`upt_id`),
  KEY `upt_user_id` (`upt_user_id`),
  KEY `upt_post_id` (`upt_post_id`),
  KEY `upt_tag_id` (`upt_tag_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=9 ;

CREATE TABLE IF NOT EXISTS `view_post` (
`post_id` int(11)
,`post_url` varchar(255)
,`post_text` text
,`post_title` varchar(255)
,`post_date` datetime
,`user_id` int(11)
,`user_display_name` varchar(128)
);

Идея состоит в том, что я хотел бы использовать наиболее эффективный способ сохранения тегов для поста и пользователей. Просто добавив сообщение, я передаю несколько тегов этому сообщению и пользователю. Позже я хотел бы иметь возможность рассчитывать вкладки для каждого пользователя и сообщения. Что-то очень похожее на переполнение стека.

Я полагаю, что tag_text должен быть уникальным? Является ли эффективным то, что я запускаю функцию каждый раз, когда я отправляю новое сообщение, чтобы просмотреть таблицу «тегов», чтобы проверить, существует ли тег, и если да, вернуть его «tag_id», чтобы я мог вставить его в таблицу «user_post_tag» .

Может быть, это плохой подход к решению проблемы такого рода.

Все предложения приветствуются.

Ответы [ 2 ]

2 голосов
/ 06 января 2010

Да, то, что вы делаете, это лучший способ сделать это. Вы создали отношение n к m, поскольку сообщение может иметь несколько тегов, и один и тот же тег может находиться в нескольких сообщениях. Вы не хотите хранить имя тега для каждого сообщения, поэтому сохраняете идентификатор.

Но вы должны -НЕТ- иметь эту избыточность хранения несколько раз одного и того же tag_id для одного и того же пользователя. Это сильно ударит по вашему серверу, если у пользователей будет несколько тегов, и вам придется выполнить SELECT count(...) для каждого из этих тегов. Вы понимаете, о чем я здесь говорю? Потому что прямо сейчас, как узнать, сколько раз пользователь A имеет тег B? Вы должны сделать SELECT count(*) FROM user_post_tag INNER JOIN tags ON (...) WHERE user_id=A and tag_id=B.

Я предлагаю разделить user_post_tag на две таблицы:

  1. user_tags, чтобы подсчитать, сколько раз у пользователя есть этот тег, первичный ключ будет user_id и tag_id, и у вас будет поле count, которое вы будете просто обновлять с помощью count=count+1 каждый раз этот пользователь создает новое сообщение с тегом. Таким образом, вы можете просто сделать SELECT tag_text, count FROM user_tags INNER JOIN tags ON (...) WHERE user_id=A, чтобы выбрать все теги (с количеством использованных раз) данного пользователя. Вы используете полностью проиндексированный запрос. Вы не просите MySQL пройтись по таблице, найти кучу строк и сосчитать их, вы говорите MySQL, перейдите эту строку в эту таблицу и в другую таблицу, присоединитесь к ним и быстро передайте мне. !
  2. post_tags, для хранения тегов, содержащихся в определенном сообщении, первичным ключом будет post_id и tag_id, дополнительные поля не требуются.

Полагаю, что tag_text должен быть уникальный? Если эффективно, что я бегу функция каждый раз, когда я отправляю новую опубликовать, чтобы пройти через таблицу тегов проверить, если тег уже существует, и если да, верните его tag_id, чтобы я мог вставьте его в таблицу user_post_tag.

Да, он должен быть уникальным. Лучше проверить, существует ли тег, прежде чем вставлять и вставлять, если он не существует, чем иметь избыточность и выполнять SELECT ... count (*), чтобы узнать, сколько раз тег использовался. Создание постов будет намного реже, чем выбор постов, поэтому, если вам нужно выбирать между интенсивным запросом при вставке и выделением, обязательно выберите вставку.

Кстати, если вы хотите подсчитать, сколько постов имеют один и тот же тег, как при переполнении стека, вам понадобится еще одна таблица с первичным ключом tag_id, а затем, как на user_tags вы увеличиваете поле count каждый раз, когда сообщение получает определенный тег.

0 голосов
/ 06 января 2010

Хммм, если все ваши теги уникальны, то вам не нужны tag_id и tag_text в таблице тегов.Просто используйте tag_text и сделайте его первичным ключом.Затем посмотрите на REPLACE INTO (http://dev.mysql.com/doc/refman/5.0/en/replace.html) для обработки новых тегов.

Связывание тегов с пользователями или публикациями - таблица user_tags и таблица post_tags. Никаких значений автоинкремента, только составной ключ с user_id и tag_text илиpost_id и tag_text. Я не знаю, смотрите ли вы на таблицу user_post_tags для повышения производительности по сравнению с присоединением таблицы post_tags к сообщениям и пользователям. Тем не менее, «замена в» должна быть вашим другом здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...