Woocommerce

Почему структура БД WordPress плохо подходит для интернет-магазина

WordPress создавался как движок блога. Позже его сделали универсальным: любая сущность (страница, запись, меню, а потом и товар) попадала в wp_posts с полем post_type. Магазин WooCommerce строился поверх готовой структуры. Это было удобно для плагинов: товары получают редактор, медиа, ревизии и комментарии по умолчанию.

Цена такого решения хорошо известна:

  1. В wp_posts лежат поля блога (post_content, post_excerpt, comment_status, ping_status), а у товара нужных ему полей (цена, остаток, артикул) в этой таблице нет.
  2. Все характеристики хранятся в wp_postmeta в виде строк (post_id, meta_key, meta_value). Значение там тип LONGTEXT, поэтому цена и диапазоны сравниваются как строки, а нормальные индексы по значениям построить нельзя.
  3. На больших каталогах это тормозит. WooCommerce сам это признал и добавил отдельную таблицу wc_product_meta_lookup с ценой, остатком и артикулом, чтобы фильтровать и сортировать быстрее. Заказы он тоже вынес из wp_posts в собственные таблицы (HPOS).

EAV-схема

Entity – Attribute – Value («сущность – атрибут – значение»)

Это способ хранить характеристики объекта не в отдельных колонках, а в виде строк: одна строка соответствует одному значению одной характеристики.

Обычная схема (колонки)

Таблица products

products
id | name        | power_kw | max_head | pump_type
1  | Джилекс 100 | 0.75     | 40       | центробежный
2  | Водолей 3   | 0.30     | 72       | вибрационный

Каждая характеристика является колонкой. Это быстро и понятно, но у разных категорий разные характеристики. Если держать всё в колонках, таблица быстро обрастает десятками пустых полей. Новая характеристика требует менять структуру таблицы (ALTER TABLE).

products                      product_attribute_values
id | name                     product_id | attribute | value
1  | Джилекс 100              1          | power_kw  | 0.75
2  | Водолей 3                1          | max_head  | 40
                              1          | pump_type | центробежный
                              2          | power_kw  | 0.30
                              2          | max_head  | 72

Плюсы и минусы

Плюсы:

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

Минусы:

  • Запросы сложнее. Чтобы получить товары с мощностью до 1 кВт и напором от 30 м, нужно несколько соединений или EXISTS.
  • Если хранить все значения как текст (как wp_postmeta в WooCommerce), нельзя нормально сравнивать числа и строить индексы по значениям.
  • Нет ограничений базы на уровне полей, поэтому проверять данные нужно в коде.

Оставить комментарий