2010-01-05 4 views
2

У меня есть следующие таблицы;Что было бы самым эффективным способом вставить теги в таблицу

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» ,

Возможно, это плохой подход к решению этой проблемы.

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

+0

Вы освободите это как открытый источник, после того как вы закончите? с «Что-то очень похожее на переполнение стека» – ant

ответ

2

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

Но, вы должны -NOT- иметь эту редуальность хранения нескольких раз один и тот же 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

Хммм, если ваши теги уникальны, вам не нужны 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 с сообщениями и пользователями. Тем не менее, «заменить в» должен быть ваш друг здесь тоже.

+0

Я бы рекомендовал придерживаться цифровых клавиш. Если вы введете текстовое поле в уникальный ключ, трюк 'REPLACE INTO' будет по-прежнему работать, и он значительно упростит переименование целого тега. – nickf