База данных для каталога товаров с несколькими магазинами, иерархическими категориями

boss спросил: 03 ноября 2018 в 08:40 в: database

Я ищу помощи в выборе наилучшей базы данных, будь то реляционной или нет, а также наилучшей схемы для данной задачи.

Идея заключается в следующем: сеть автономных магазинов с несколькими магазинами (~ 10). В каждом магазине есть несколько товаров (~ 100000), которые распределяются между ними, но доступность и цены / скидки различаются. Продукты структурированы в иерархические категории (~ 1000). Некоторые категории могут быть дисконтными. Некоторые нет. Некоторые продукты могут быть только для взрослых. Товары имеют различные атрибуты.

Требуемые запросы:

  • Получить полное дерево категорий (ограничено уровнем вложенности) для данного магазина с продуктами, доступными в настоящее время (отфильтрованные по флагу для взрослых). ).
  • Получить некоторое поддерево по заданному идентификатору категории для данного магазина с продуктами, которые в настоящее время доступны.
  • Получить дерево для категорий только со скидкой для данного магазина с продуктами, имеющимися в настоящее время и имеющими скидку. .
  • Получите разбитый на страницы список доступных на данный момент товаров для данного магазина в данной категории, включая подкатегории, отфильтрованные по взрослым.
  • Получите сведения об одном продукте с полным списком атрибутов.
  • Фильтрация продуктов по атрибутам.

Текущее решение основано на базе данных Oracle со следующей схемой:

Таблицы: stores, products, categories (иерархия через MPTT), products_categories (ссылки products и categories), (ссылки productprices и stores), products (ссылки attributes

Это вроде работает, но начинает работать медленно. Например, запрос для получения категорий с доступными продуктами иногда выполняется менее чем за секунду, а иногда - более 30, в зависимости от данных, импортируемых в настоящее время в базе данных.

Соответствующий запрос:

SELECT "categories".* FROM "categories"
WHERE (
  NOT ("categories"."external_id" = '_reserved' AND "categories"."external_id" IS NOT NULL)
  AND "categories"."is_promo" = 0
  AND "categories"."begins_on" <= to_timestamp('2018-11-27', 'YYYY-MM-DD')
  AND "categories"."ends_on" >= to_timestamp('2018-11-27', 'YYYY-MM-DD')
  AND (EXISTS(
    SELECT U0."id" FROM "productprices" U0
    INNER JOIN "products" U1 ON (U0."product_id" = U1."id")
    INNER JOIN "products_categories" U2 ON (U1."id" = U2."product_id")
    WHERE (
      U2."category_id" = ("categories"."id")
      AND U0."updated_at" >= to_timestamp('2018-11-27 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
      AND U0."store_id" = 42
      AND U0."begins_on" <= to_timestamp('2018-11-27 09:00:00', 'YYYY-MM-DD HH24:MI:SS')
      AND U0."ends_on" >= to_timestamp('2018-11-27 09:00:00', 'YYYY-MM-DD HH24:MI:SS')
      AND (U0."discount" IS NOT NULL OR U1."has_special_offer" = 1)
      AND U1."is_adult" = 0))
  )
)
ORDER BY "categories"."tree_id" ASC, "categories"."lft" ASC

В настоящее время мы собираемся начать миграцию с Oracle Database. Основной базой данных приложения будет Postgres, но для части каталога приложения я хочу взглянуть на другое хранилище. Или, может быть, мне следует просто оптимизировать схему / запросы?

В настоящее время существует 15 магазинов, в которые добавляется ~ 4 магазина в год. Насколько я знаю, никогда не должно быть более 200 000 товаров. С 25 магазинами он ограничивает таблицу цен на 5 000 000 строк в обозримом будущем.

0 ответов