Как извлечь информацию из модели данных EAV (сущность-атрибут-значение)?

Изображение к вопросу
  • 5 сентября 2023 г. 17:48
Ответы на вопрос 2
Конечно! В Postgres 13 стандартная структура базы данных представляет собой набор таблиц, где каждая таблица состоит из строк и столбцов. Каждая строка в таблице обычно представляет собой отдельную сущность, а столбцы представляют атрибуты или свойства этой сущности.

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

Для извлечения информации из модели данных EAV в Postgres 13 могут использоваться различные подходы и запросы. Один из способов - это использование оператора JOIN для связывания строк сущностей, атрибутов и значений. Например, для получения всех значений атрибута "имя" можно написать следующий запрос:

SELECT E.entity, V.value
FROM entities E
JOIN attributes A ON E.entity_id = A.entity_id
JOIN values V ON A.attribute_id = V.attribute_id
WHERE A.attribute = 'имя'

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

SELECT E.entity, V.value
FROM entities E
JOIN attributes A ON E.entity_id = A.entity_id
JOIN values V ON A.attribute_id = V.attribute_id
WHERE E.entity = 'сущность1' AND A.attribute = 'имя'

При использовании структуры данных EAV важно учитывать, что она может привести к сложности с производительностью запросов и сложности чтения и понимания данных. Поэтому перед принятием решения об использовании EAV важно оценить все преимущества и недостатки этого подхода в контексте конкретной задачи.
SELECT
    p.id,
    p.name,
    json_agg(
        json_build_object(
            'name', eav_attribute.name,
            'text_value', eav_val_text.val,
            'real_value',eav_val_real.val,
            'bool_value', eav_val_boolean.val
        )
    ) AS characteristics,
    COUNT(*) OVER() AS total
FROM product AS p
LEFT JOIN eav_entity AS ee ON p.category_id = ee.category_id
LEFT JOIN eav_attribute ON ee.eav_attribute_id = eav_attribute.id
LEFT JOIN eav_val_text ON ee.id = eav_val_text.attribute_id 
LEFT JOIN eav_val_real ON ee.id = eav_val_real.attribute_id 
LEFT JOIN eav_val_boolean ON ee.id = eav_val_boolean.attribute_id
WHERE eav_val_text.attribute_id = 2
GROUP BY p.id, p.name;
Похожие вопросы