Обновите списки тегов или обновите отношения has_many

Я часто сталкиваюсь с проблемой обновления имеет много связей. Например, возьмем следующие три таблицы:

  • сообщения
  • теги
  • сообщения_теги

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

Когда пользователь редактирует сообщение (и может редактировать или не редактировать список тегов), и форма отправляется, я должен обновить список тегов сообщения.

Решение может быть следующим: при обновлении поста я удаляю все теги этого поста из _posts_tags_, и вставляю отправленные.

Другое решение — получить все теги поста из БД, сравнить список с представленным и решить, что нам нужно удалить, а что — вставить.

Оба решения могут занять много времени.
Какое решение проблемы может быть более разумным?


person Tamás Pap    schedule 15.05.2012    source источник
comment
Я немного устал и сонный, так что потерпите меня (возможно, я неправильно прочитал это), но разве каскадирование не для этого?   -  person Bono    schedule 15.05.2012
comment
@Bono: Нет. Вопрос не в том, как каскадировать обновления между связанными записями во внешних таблицах, а в том, как определить, какие из набора записей были изменены в приложении, чтобы отразить эти изменения в базе данных.   -  person eggyal    schedule 15.05.2012
comment
Из двух опубликованных вами решений первое часто будет предпочтительнее. Удаление с использованием индекса будет быстрее, чем тип сравнения, требуемый вторым. Что касается поиска более умного решения, следует ли вам применить здесь принцип KISS?   -  person George Cummins    schedule 15.05.2012


Ответы (1)


Когда пост редактируется, а теги не редактируются (необязательно), просто сохраните пост и ничего не делайте. Почему? Потому что в таблицах posts, tags и posts_tags у вас есть столбец автоинкремента, который является вашим первичным ключом. Этот числовой столбец является внешним ключом в соответствующих таблицах, т.е. таблицы будут выглядеть следующим образом:

сообщения: id_post(PK), post_title, post_content

Теги: id_tag(PK), tag_name

posts_tags: id_post_tag (PK), id_post (FK), id_tag ​​(FK)

PK: первичный ключ FK: внешний ключ

Сохранив данные в этом формате, вы обнаружите, что вам не нужно обновлять какую-либо зависимую таблицу, поскольку текстовые данные больше не используются для поддержания схемы базы данных и связей. Это также ускоряет время транзакций, поскольку база данных не занята ни одним каскадным заданием, как предполагал Боно.

Затем запустите простой цикл для всех тегов в сообщении, чтобы проверить их существование по id_post в таблице post_tags и, если они не найдены, вставьте их. При выполнении этого цикла создайте строку, которую вы будете использовать ниже:

Далее выполните следующий запрос:

delete from post_tags where id_post = {$id_post} and id_tag not in {$list_id_tags}

Эта операция сводит к минимуму перегрузку сервера базы данных за счет минимизации операций ввода-вывода, вызванных добавлением и удалением строк. Ваш случай удаления всех post_tags и повторной вставки всех тегов привел бы к большому вводу-выводу, в то время как этот метод минимизирует это.

person somnath    schedule 15.05.2012