такое EAV - Гибрид плохой выбор дизайна базы данных - PullRequest
17 голосов
/ 19 декабря 2010

Мы должны перепроектировать устаревшую базу данных POI из MySQL в PostgreSQL. В настоящее время все сущности имеют 80-120 + атрибутов, которые представляют отдельные свойства.

Нас попросили рассмотреть гибкость, а также хороший подход к проектированию новой базы данных. Однако новый дизайн должен позволять:

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

  • позволяют администраторам контента добавлять новые свойства к существующим объектам на лету , используя через интерфейсы администратора, вместо того, чтобы постоянно вносить изменения в схему БД.

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

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

В любом случае, вот что мы думаем о новом дизайне (включая базовый ERD):

  • Для каждой сущности есть отдельные таблицы, содержащие основную информацию, которая является эксклюзивной, например, идентификатор, имя, адрес, контакт, созданный и т. д. и т. д.

  • Имеют 2 типа атрибута таблицы и атрибут для хранения информации о свойствах.

  • Свяжите каждую сущность с атрибутом, используя отношение «многие ко многим».

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

alt text

Мы считаем, что это позволит нам быть более гибкими при добавлении, удалении или обновлении свойств.

Однако этот дизайн приведет к увеличению числа объединений при извлечении данных, например, для отображения всех «атрибутов» для данного стадиона. У нас может быть запрос с 20+ объединениями, чтобы извлечь все связанные атрибуты в одной строке.

Что вы думаете об этом дизайне и что бы вы посоветовали улучшить?

Спасибо за чтение.

Ответы [ 4 ]

30 голосов
/ 24 декабря 2010

Я поддерживаю 10-летнюю систему, которая имеет центральную модель EAV с 10M + сущностями, 500M + значениями и сотнями атрибутов.Некоторые соображения по проектированию из моего опыта:

Если у вас есть какая-либо бизнес-логика, которая относится к определенному атрибуту, стоит иметь этот атрибут в качестве явного столбца.Атрибуты EAV должны быть действительно универсальными, приложение не должно отличать атрибут A от атрибута B. Если вы обнаружите в коде буквальную ссылку на атрибут EAV, вероятно, это будет явный столбец.

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

  • Имеются соглашения и правила, которые позволяют вам знать, какая часть вашего приложения считывает и изменяет какую часть данных.
  • Использование представлений для облегчения работы с базой данных с помощью инструментов отладки.
  • Создание и поддержка генераторов тестовых данных, чтобы вы могли легко создавать фиктивные фиктивные данные, соответствующие схеме, для частей модели, которые в данный момент не используются.Заинтересованы в.
  • Используйте строгие версии базы данных.Единственный способ внести изменения в схему должен быть через инструмент, который отслеживает и применяет сценарии изменений.Postgresql имеет транзакционный DDL, который является одной из самых гибких функций для автоматизации изменений схемы.

Postgresql на самом деле не любит узкие таблицы.Каждое значение атрибута приводит к 32 байтам хранения данных в дополнение к дополнительной работе по обходу всех строк для объединения данных.Если вы в основном читаете и записываете атрибуты как пакет, рассмотрите возможность сериализации данных в строку каким-либо образом.attr_ids int[], attr_values text[] - это один вариант, hstore - другой, или что-то на стороне клиента, например, json или protobuf, если вам не нужно прикасаться к чему-то конкретному на стороне базы данных.

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

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

6 голосов
/ 19 декабря 2010

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

Я думаю, что "сущность" слишком общая. Похоже, у вас есть представление о том, что должно быть связано с этим объектом, например адрес и контакт. Что делать, если вы решили иметь «Книги» в модели. Будут ли у них также адреса и контакты? Я думаю, что вы должны попытаться найти правильные обобщения и сохранить EAV-части модели на минимуме. Всякий раз, когда вы обнаружите, что хотите показать определенное подмножество атрибутов, или проверить наличие значения, или определить поведение на основе значения, вы должны действительно смоделировать его как столбцы.

У вас не будет лучшей возможности разработать эту систему, чем сейчас. Требования известны с предыдущей версии, а также то, что работало, а что нет. (Только не становитесь жертвой Второго системного эффекта )

3 голосов
/ 08 января 2013

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

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

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

2 голосов
/ 19 декабря 2010

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

Я написал системы EAV для ограниченных приложений, но в качестве общего решения обычноплохая идея.

...