EAV против организации на основе столбцов для моих данных - PullRequest
0 голосов
/ 19 января 2012

Я нахожусь в процессе перестройки приложения (здесь одинокий разработчик) с использованием PHP и PostgreSQL. Для большей части данных я храню их, используя таблицу с несколькими столбцами для каждого атрибута. Однако сейчас я начинаю создавать некоторые таблицы для хранения контента. Контент в этом случае состоит из нескольких разделов, каждый из которых содержит разные наборы данных; некоторые данные являются общими и общими (и внешние ключи), а другие данные являются уникальными. В текущей итерации приложения мы имеем следующую структуру таблицы:

id | project_name | project_owner | site | customer_name | last_updated
-----------------------------------------------------------------------
1  | test1        | some guy      | 12   | some company  | 1/2/2012
2  | test2        | another guy   | 04   | another co    | 2/22/2012

Теперь, это работает - но его трудно поддерживать по нескольким причинам. Добавление новых столбцов (случается редко) требует изменения таблицы базы данных. Для аудита / отслеживания истории требуется отдельная таблица, которая отражает основную таблицу с дополнительной информацией, что также требует изменения в случае изменения основной таблицы. Наконец, столбцов много - более 100 в некоторых таблицах.

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

Подход, который я сейчас рассматриваю, кажется, называется моделью EAV. У меня есть таблица, которая выглядит так:

id | project_name | col_name | data_varchar      | data_int | data_timestamp | update_time
--------------------------------------------------------------------------------------------------
1  | test1        | site     |                   | 12       |                | 1/2/2012
2  | test1        | customer_name | some company |          |                | 1/2/2012
3  | test1        | project_owner | some guy     |          |                | 1/2/2012

... и так далее. Это имеет то преимущество, что я никогда не обновляюсь, всегда вставляю. Данные никогда не перезаписываются, только добавляются. Конечно, стол в конечном итоге станет довольно большим. У меня есть таблица «index», в которой перечислены проекты и которая используется для ссылки на таблицу «data». Однако я чувствую, что мне не хватает чего-то большого с этим подходом. Будет ли это масштабироваться? Первоначально я хотел создать простую таблицу ключей -> значений, но понял, что мне нужно иметь возможность иметь разные типы данных в таблице. Это кажется управляемым, потому что слой абстракции базы данных, который я использую, будет включать тип, который выбирает данные из соответствующего столбца.

Я делаю слишком много для себя? Должен ли я придерживаться простой таблицы с тонной столбцов?

Ответы [ 2 ]

3 голосов
/ 19 января 2012

Мой совет: если вы можете избежать использования таблицы EAV, сделайте это. Они имеют тенденцию быть убийцами производительности. Их также сложно правильно запрашивать, особенно для отчетов (да, я могу присоединиться к этой таблице неизвестное число раз, чтобы получить все нужные мне данные и, о, кстати, я не знаю, какие столбцы у меня есть поэтому я понятия не имею, какие столбцы должен содержать отчет), и трудно получить тип ограничений базы данных, которые необходимы для обеспечения целостности данных (например, как обеспечить заполнение обязательных полей), и это может привести к вам использовать плохие типы данных. В конечном счете, гораздо лучше определить таблицы, в которых хранятся нужные вам данные.

Если вам действительно нужна функциональность, то, по крайней мере, посмотрите на базы данных NoSQL, которые более оптимизированы для такого рода неопределенных данных.

0 голосов
/ 19 января 2012

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

Обратите внимание, однако, что восстановление старых версий записей нетривиально с журналом аудита EAV и потребует значительного количества кода приложения.База данных не сможет сделать это сама.

Альтернативой, которую вы могли бы рассмотреть, является сохранение всех ваших данных (новых и старых записей) в той же самой таблице .Вы можете включить поля аудита в одну и ту же таблицу и оставить NULL, когда в этом нет необходимости, или сохранить некоторые строки в таблице как «текущие», а связанные с аудитом поля хранятся в другой таблице.Чтобы упростить ваше приложение, вы можете создать представление, которое отображает только текущие строки и выполнить запросы к представлению.

Это можно сделать с помощью шаблона наследования объединенной таблицы.С наследованием объединенной таблицы вы помещаете общие атрибуты в базовую таблицу вместе со столбцом типа и можете присоединяться к дополнительным таблицам (которые имеют тот же первичный ключ, который также является внешним ключом) на основе типа.Многие ORM Data-Mapper-Pattern имеют встроенную поддержку этого шаблона, часто называемую «полиморфизмом».

Вы также можете использовать собственный механизм наследования таблиц PostgreSQL , но обратите внимание на предостережения!

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