2011-02-22 2 views
0

Этот вопрос поднялся во многих случаях для меня, но его трудно объяснить, не указав конкретного примера. Итак, здесь идет речь:Сериализация или сохранение отдельной таблицы?

Давайте немного подумаем, что мы создаем базу данных отслеживания проблем в PHP/MySQL. Существует таблица «задач». Теперь вам нужно отслеживать людей, которые связаны с конкретной задачей (прокомментировали или нет). Эти люди получат электронное письмо при изменении задачи.

Существует два способа решить эту ситуацию. Одним из них является создание отдельной таблице tasks_participants:

CREATE TABLE IF NOT EXISTS `task_participants` (
    `task_id` int(10) unsigned NOT NULL, 
    `person_id` int(10) unsigned NOT NULL, 
    UNIQUE KEY `task_id_person_id` (`task_id`,`person_id`) 
); 

И запросить эту таблицу с SELECT person_id WHERE task_id='XXX'.

Если есть 5000 задач, и каждая задача состоит из 4 участников в среднем (репортер, субъект, для которого задача принесла пользу, решатель и один комментатор), тогда таблица task_participants будет 5000 * 4 = 20 000 строк.

Существует также другой способ: создать поле в таблице задач и хранить сериализованный массив (JSON или PHP serialize()) person_id. Тогда не понадобится эта таблица из 20 000 строк.

Ваши комментарии, в какую сторону вы бы хотели пойти?

ответ

6

Пойдите с несколькими записями. Это способствует нормализации базы данных. Нормализация очень важна. Обновление сериализованного значения не является забавой для поддержки. С несколькими записями я могу позволить базе данных выполнять работу с INSERT, UPDATE и DELETE. Кроме того, вы ограничиваете свое будущее объединением, имея многозначную колонку.

+1

Это именно тот ответ, который я бы дал :) @OP: http://en.wikipedia.org/wiki/Database_normalization заслуживает внимания и для дальнейших подробностей. –

+0

Также посмотрите, как должна быть смоделирована роль человека. Я предполагаю, что участник «назначенный» должен быть непосредственно привязан в таблице задач. У меня также была бы таблица комментариев, содержащая ссылку на автора. –

1

Определенно сделайте таблицу перекрестных ссылок (первый вариант, который вы указали). Зачем?

  • Прежде всего, не беспокоиться о размере поперечного ссылочной таблицы. Реляционные базы данных были бы на их ухе десятилетиями назад, если бы они не могли справиться с масштабами простой перекрестной справочной таблицы. Перестаньте беспокоиться о записях 20К или 200К и т. Д. На самом деле, если вы собираетесь беспокоиться о чем-то подобном, лучше начать беспокоиться о том, почему вы выбрали реляционную БД вместо базы данных с ключом. После этого, и только когда это действительно начинает быть проблемой, вы можете начать беспокоиться о добавлении индекса или других методов настройки.

  • Во-вторых, если вы сериализовать информацию об ассоциации, вы вероятно непрозрачного ifying весь размер ваших данных, которые только ваши специализированные JSON с поддержкой приложение может запросить. Сериализация данных в одну ячейку в таблице, как правило, имеет смысл только в том случае, если внедренная структура (a) не является чем-то, что содержит данные, которые вам никогда не потребуется запрашивать вне вашего приложения, (b) это не то, что вам нужно для запроса внутренних элементов (например, avg count (*) людей с задачами), и (c) - это просто то, что вы либо не успеваете правильно смоделировать, либо находится в прототипическом состоянии. Поэтому я говорю , вероятно, выше, потому что обычно не так, что данные, стоящие настойчиво, соответствуют этим критериям.

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

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

0

Уже есть несколько отличных ответов, но они объясняют вещи довольно теоретически. Вот мой (по сути идентичный) ответ, на простом английском языке:

1) 20k records is ничего не найдено. Если он встанет в 20-миллионный диапазон записей, то вы можете начать беспокоиться, но это, вероятно, не будет проблемой.

2) Хорошо, давайте предположим, что вы отправились с конкатенацией всех людей, связанных с билетом, в одно поле. Теперь ... Быстрый! Скажи мне, сколько билетов Алиса коснулась! У меня такое чувство, что Боб набирает обороты, и Чарли покрывает его. Можете ли вы получить мне список билетов, на которые они оба работали, и поделили их последними?

С отдельной таблицей MySQL может найти ответы на все вопросы о том, кто работал над тем, какие билеты можно найти, и может найти их быстро. Со всем, что переполнено в одно поле, вам в значительной степени приходится прибегать к использованию LIKE запросов, чтобы найти (потенциально) релевантные записи, а затем обработать результаты запроса, чтобы извлечь важные данные и суммировать их самостоятельно.

Смежные вопросы