Ответ 1
Независимо от MS SQL Server по сравнению с любым другим брендом базы данных, наихудшая проблема с производительностью EAV заключается в том, что люди пытаются выполнять запросы монстров для восстановления объекта в одной строке. Для этого требуется отдельное соединение для каждого атрибута.
SELECT e.id, a1.attr_value as "cost", a2.attr_value as "color",
a3.attr_value as "size", . . .
FROM entity e
LEFT OUTER JOIN attrib a1 ON (e.entity_id = a1.entity_id AND a1.attr_name = 'cost')
LEFT OUTER JOIN attrib a2 ON (e.entity_id = a2.entity_id AND a2.attr_name = 'color')
LEFT OUTER JOIN attrib a2 ON (e.entity_id = a3.entity_id AND a3.attr_name = 'size')
. . . additional joins for each attribute . . .
Независимо от того, какой бренд базы данных вы используете, большее количество подключений в запросе означает геометрически увеличивающуюся стоимость работы. Неизбежно, вам нужно достаточно атрибутов, чтобы превысить архитектурные возможности любого механизма SQL.
Решение состоит в том, чтобы извлекать атрибуты в строках вместо столбцов и записывать класс в код приложения для циклизации по этим строкам, присваивая значения свойствам объекта по одному.
SELECT e.id, a.attr_name, a.attr_value
FROM entity e JOIN attrib a USING (entity_id)
ORDER BY e.id;
Этот SQL-запрос настолько прост и эффективен, что он учитывает дополнительный код приложения.
То, что я искал бы в структуре EAV, - это некоторый шаблонный код, который извлекает многострочный результат, подобный этому, и сопоставляет атрибуты в свойствах объекта, а затем возвращает коллекцию заполненных объектов.