Найти тему
Рустам Алиев

EAV-модель данных. Общие принципы, правила, плюсы и минусы. Часть 3.

EAV: Минусы
EAV: Минусы

В предыдущей серии этого сериала:

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

Перейдём к недостаткам

Основной очевидный недостаток - сложность при построении запросов. Для того, чтобы добавить сущность необходимо минимум 2 команды вставки, при условии, что все атрибуты описаны ранее:

  • 1 команда для вставки в таблицу сущностей;
  • 1 команда для вставки значений описываемых атрибутов сущности.

Такая же ситуация при получении сведений - для получения всех характеристик сущности необходимо использовать либо команду JOIN по одной для каждого атрибута, либо вложенные запросы по одному для каждого требуемого атрибута.

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

В предыдущих статьях приведён ряд примеров, которые подтвердили этот недостаток, хотя и не имели такой цели.

Следующим недостатком является отсутствие контроля целостности данных. Разберём пример:

"Я - ужас, летящий на крыльях ночи! Я - чёрный плащ!"

Отразим в РСУБД стандартным подходом

Структура основывалась только на имеющихся данных
Структура основывалась только на имеющихся данных
Создание таблиц с помощью стандартного подхода

Разместим данные в этой структуре

Данные в структуре
Данные в структуре

Используя именно такую структуру при размещении данных мы можем получить только исходную фразу и никакую другую. Фраза

"Я - плащ, летящий на крыльях ночи! Я - черный ужас!"

имеет смысл с точки зрения лексики, но сильно отличается от первоначального замысла и при соблюдении последовательного использования команд JOIN такая фраза в принципе не возможна, т.к. цельность фразы обеспечивается связями между таблицами.

Удаление одного свойства из таблицы Properties приведёт к исчезновению из результатов запроса не только самой записи, но и связанных с ней, подчинённых записей из таблицы PropertCharacteristics не зависимо от того, как эти связи настроены (delete/setNull).

Разместим теперь имеющиеся данные в структуре EAV, где используются поля разных типов, для хранения значений разных типов

Структура EAV, используемая в прошлой части
Структура EAV, используемая в прошлой части
Скрипт создания таблиц для отражения любой сущности

Размещая данные в этой структуре мы можем пойти разными путями. В этот раз мы пойдём более сложным путём, добавив новые сущности и связи между ними.

Клик по изображению увеличит его
Клик по изображению увеличит его

Если в структуре, созданной стандартным подходом сразу очевидно, каким образом можно получить данные, то в этом случае есть проблемы с пониманием:

Неочевидная связь между сущностями при использовании INNER JOIN и условий в команде WHERE
Неочевидная связь между сущностями при использовании INNER JOIN и условий в команде WHERE
Неочевидная связь между сущностями при использовании INNER JOIN и условий в команде WHERE

Так же, удаление одной из связанных сущностей не приведёт с null-результату запроса, а просто в некоторых полях будут значения null. К примеру если мы удалим плащ, это не изменит количество строк, возвращаемых запросом. Изменятся значения полей. Если удалим "Плащ", то фраза будет по--прежнему выводится, но уже в изменённом виде:

Я - ужас, летящий на крыльях ночи! Я - null null!

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

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

Последний из основных недостатков - низкая производительность при построении запросов.

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

Очевидно, что при прочих равных условиях (наличие индексов, выбранная СУБД, целостность и нормализация данных) запрос к таблицам, которые построены при использовании стандартного подхода к структуре данных (назовём структуру - А) будет выполняться быстрее, чем запрос к таблицам, которые построены при использовании EAV-модели (это будет структура Б).

В случае использования структуры А нет необходимости:

1. Использовать вложенные запросы

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

В то время, как в структуре Б при запросе у нас таблица valueAttributes используется несколько раз только в рамках одного запроса.

Тут даже бенчмарки проводить нет смысла - происходит много обращений к одним и тем же таблицам.

К итогам

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

Использовать EAV-модель данных я рекомендую только в следующих случаях:

  1. При постановке задачи имеется масса вводных, которые описаны не конкретно в связи с тем, что заказчик ещё сам не понимает, как это будет выглядеть. Бизнес не готов сформулировать полный перечень атрибутов и сущностей, которые подлежат хранению, т.к. либо бизнес о них в данный момент не знает, либо бизнес на их реализации на текущем этапе не настаивает.
  2. Никто из вашей команды не имеет физического доступа к серверам СУБД, включая команду администраторов.
  3. Вам необходимо за минимальное время собрать MVP, который будет эксплуатироваться заказчиком и одновременно с этим будут вноситься новые коррективы в список атрибутов и сущностей.

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

Предыдущая статья | Следующая статья