Основные недостатки в проектах баз данных Entity-Attribute-Value в SQL, по-видимому, связаны с возможностью эффективного и быстрого запроса и составления отчетов по данным. Большая часть информации, которую я читаю по этому вопросу, предостерегает от внедрения EAV из-за этих проблем и общности запросов / отчетов почти для всех приложений.
В настоящее время я разрабатываю систему, в которой поля для одного из объектов не известны во время разработки / компиляции и определяются конечным пользователем системы. EAV кажется подходящим для этого требования, но из-за проблем, о которых я читал, я не решаюсь его реализовать, так как для этой системы также существуют довольно жесткие требования к отчетности. Я думаю Я нашел способ обойти это, но хотел бы задать вопрос SO-сообществу.
Учитывая, что типичная нормализованная база данных (OLTP) по-прежнему не всегда является оптимальным вариантом для запуска отчетов, рекомендуется использовать базу данных «отчетности» (OLAP), в которую данные из нормализованной базы данных копируются, индексируются экстенсивно и, возможно, денормализовано для облегчения запросов. Может ли та же идея быть использована для обхода недостатков дизайна EAV?
Основным недостатком, который я вижу, является повышенная сложность переноса данных из базы данных EAV в отчеты, так как вам может потребоваться изменить таблицы в базе данных отчетов, так как в базе данных EAV определены новые поля. Но это вряд ли невозможно и, кажется, является приемлемым компромиссом для повышенной гибкости, обеспечиваемой дизайном EAV. Этот недостаток также существует, если я использую хранилище данных, отличное от SQL (например, CouchDB или подобное), для основного хранилища данных, поскольку все стандартные инструменты отчетности ожидают, что бэкэнд SQL будет выполнять запросы.
Устранены ли проблемы с системами EAV, если у вас есть отдельная база данных отчетов для запросов?
РЕДАКТИРОВАТЬ: Спасибо за комментарии до сих пор. Одна из важных вещей в системе, над которой я работаю, это то, что я на самом деле говорю только об использовании EAV для одного из объектов, а не всего в системе.
Вся суть системы заключается в том, чтобы иметь возможность извлекать данные из нескольких разрозненных источников, которые не известны заранее, и обрабатывать данные, чтобы получить некоторые «наиболее известные» данные о конкретной сущности. Таким образом, каждое «поле», с которым я имею дело, является многозначным, и я также должен отслеживать историю каждого из них. Нормализованный дизайн для этого в конечном итоге составляет 1 таблицу на поле, что делает его запрос в любом случае болезненным.
Вот схемы таблиц и примеры данных, на которые я смотрю (очевидно, они изменились по сравнению с тем, над чем я работаю, но я думаю, что это хорошо иллюстрирует данный момент):
Таблицы EAV
Person
-------------------
- Id - Name -
-------------------
- 123 - Joe Smith -
-------------------
Person_Value
-------------------------------------------------------------------
- PersonId - Source - Field - Value - EffectiveDate -
-------------------------------------------------------------------
- 123 - CIA - HomeAddress - 123 Cherry Ln - 2010-03-26 -
- 123 - DMV - HomeAddress - 561 Stoney Rd - 2010-02-15 -
- 123 - FBI - HomeAddress - 676 Lancas Dr - 2010-03-01 -
-------------------------------------------------------------------
Таблица отчетности
Person_Denormalized
----------------------------------------------------------------------------------------
- Id - Name - HomeAddress - HomeAddress_Confidence - HomeAddress_EffectiveDate -
----------------------------------------------------------------------------------------
- 123 - Joe Smith - 123 Cherry Ln - 0.713 - 2010-03-26 -
----------------------------------------------------------------------------------------
Нормализованный дизайн
Person
-------------------
- Id - Name -
-------------------
- 123 - Joe Smith -
-------------------
Person_HomeAddress
------------------------------------------------------
- PersonId - Source - Value - Effective Date -
------------------------------------------------------
- 123 - CIA - 123 Cherry Ln - 2010-03-26 -
- 123 - DMV - 561 Stoney Rd - 2010-02-15 -
- 123 - FBI - 676 Lancas Dr - 2010-03-01 -
------------------------------------------------------
Поле «Доверие» здесь генерируется с использованием логики, которую нельзя выразить легко (если вообще) с помощью SQL, поэтому моей самой распространенной операцией, помимо вставки новых значений, будет получение ВСЕХ данных о человеке для всех полей, чтобы я мог сгенерировать запись для таблицы отчетности. На самом деле это проще в модели EAV, так как я могу сделать один запрос. В нормализованном дизайне мне приходится выполнять по одному запросу на поле, чтобы избежать объединения массивного декартового произведения.