Базы данных « Структура хранения комментариев для нескольких типов данных

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

Вопрос: есть ли удобный/оптимальный/правильный вариант хранения всех комментов в одной таблице или же просто создать несколько таблиц под каждый тип данных? Какие в этом плюсы/минусы?

Спасибо.

UPD Умные люди со StackOverflow рекомендуют писать все в одну таблицу:
http://stackoverflow.com/questions/2002985/mysql-conditional-foreign-key-constraints (см. ответ Билла Карвина)
http://stackoverflow.com/questions/3055229/generic-database-table-design

Что вы думаете по этому поводу?

1 ответов


Создавайте отдельные таблицы для каждого раздела с комментариями.
Умные люди со StackOverflow очевидно никогда не пытались разнести большие таблицы по нескольким машинам и не мигрировали с одного хранилища на другое.

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

То что вы приобретёте - гибкость и управляемость на больших объёмах.


Например

IMAGE
id
object_id

ARTICLE
id
object_id

OBJECT
id

COMMENT
id
object_id

при создании первого комментария или статьи, создается уникальный номер объекта, к которому и привязываются коментарии.


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

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

Соответственно: (Здесь количественная характеристика - сложность)

  • Стратегия хранения сущностей JOINED (обращаемся к подходу J2EE), максимально подходит от больших до огромных систем, причем мифический провал производительности на JOIN - странная выдумка индусов, т.к. мой опыт по связыванию многих десятков таблиц JOIN-ом показывает отсутствие проблем с производительностью;
  • Стратегия SINGLE_TABLE подходит от малых до средних систем включительно, особенно если нет проблем с размером хранилища и есть возможность хранить Nullable значения сущностей;
  • Стратегия TABLE_PER_CLASS подходит от малых до средних систем, но здесь присутствует огромный провал в производительности, когда необходимо обработать массив комментариев более, чем одной сущности.

Очень надеюсь, что вопрос производительности выборки из таблицы с количеством записей более миллиона будет отдан на откуп грамотным администраторам СУБД, которые однозначно смогут реализовать хранение даже одной таблицы, обеспечивающее производительность выборки сопоставимую с хранением в разных таблицах.

Хранение части данных одной таблицы, разбитых по сущностям, в разных физических локациях, не представляет проблемы для промышленных СУБД без ручного data reallocation, соответственно, все проблемы "малых" СУБД, приводящие к ухищрениям в хранении и усложняющие дальнейшее сопровождение, отсутствуют.