14 июня 2016 г. 17:55

713

Использование EAV при разработке интернет-магазинов

При разработке интернет-магазинов, товары могут иметь различные наборы атрибутов. То есть у нас могут быть два товара ,у которых есть одинаковые атрибуты , такие как цена и артикул , но также у них могут быть различные атрибуты. Добавлять все атрибуты в таблицу товаров мы не можем , так как мы хотим в дальнейшем большей гибкости.Для решения данной задачи часто прибегают к EAV(Entity-Attribute-Vaue). В качестве альтернативы используются NOSQL решения и Postgresql JSON.

Что за зверь EAV ??

Архитектура баз данных EAV(Enity-Attribute-Value, Сущность-Атрибут-Значение) состоит как видно из названия из следующих компонентов, которые мы рассмотрим поподробнее:

Entity(Сущность) - может быть представлена товарами, категориями и другими элементами данных. В нашем случае сущностью является товары.

Attribute(Атрибуты) - каждая сущность имеет свои характеристики. В данном случае , товары могут иметь атрибуты как цена , артикул,вес и прочие

Value(Значение) - это просто конкретное значение атрибута. Допустим , атрибут Диагональ для товара Ноутбук может иметь значение 15 дюймов.

В простейшем случае EAV можно представить двумя таблицами. Таблица catalog_product(это товары), а таблица catalog_productattribute(атрибуты со значениями).

Но наиболее часто , реализация EAV состоит из трех таблиц.

Entity Attribute Value

Здесь у нас имеется три таблицы

Таблица catalog_product - это таблица товаров

Таблица catalog_productattribute - это таблица атрибутов , которая связана с таблицей продуктов по внешнему ключу

Таблица catalog_productattributevalue - это таблица значений , которая связана с таблицей товаров(catalog_product) и с таблицей атрибутов(catalog_productattribute).

Закрепим это на примерах. Как отмечали выше , у нас есть ноутбук и у него может быть атрибут диагональ, который равень 15 дюймов. В таблицу catalog_product мы добавляем ноутбук Lenovo. А в таблицу catalog_productattribute добавим диагональ


INSERT INTO catalog_product(name, artikul, price) VALUES('Lenovo 1', '12345', 30000);
INSERT INTO catalog_productattribute(name, code, type) VALUES('Диагональ', 'diagonal','float');

Как мы видим , у нас добавился сам товар и сам атрибут

Теперь для добавленного товара мы установим значение атрибута


INSERT INTO catalog_productattributevalue(attribute_id, product_id, value_float) VALUES(1,1,15);

Аналогично можно добавить товар книгу Преступление и наказание и с атрибутом Количество страниц равное 672 страницам. Таким образом мы программно через интерфейс можем добавлять новые атрибуты специфичные для определенных товаров.

В реальных интернет-магазинах я использую расширенную версию. Так как у нас добавляются категории для товаров , то соответсвенно привязываю атрибуты к категориям. И еще у нас добавляется новый тип данных Enum

EAV antipattern

Заключение

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

Альтернативные способы сделать динамические поля , это использование NoSql решений и Postgresql JSON . Но это уже другая история и про них я расскажу в следующих статьях

comments powered by Disqus