Электронная коммерция, разделение товаров по категориям и просмотр категорий

StackOverflow https://stackoverflow.com/questions/1641397

  •  08-07-2019
  •  | 
  •  

Вопрос

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

Вот моя основная проблема и краткое описание того, как настраивается система:товары находятся внутри категорий, категории могут быть дочерними элементами другой категории.Таким образом, категория представлена в виде дерева на левой боковой панели веб-сайта.

Пользователь может просматривать любую категорию, даже не "конечную" категорию, если пользователь нажимает на не конечную категорию, подобный список должен быть представлен, например, в категории уровня 1 (то же самое относится к категориям уровня 2):

big category 1
 category level ( 3 or 2 )
  product 1
  product 2
  product 3
 category level ( 3 or 2 ) 

Вещи также должны иметь некоторую разбитость на страницы и присутствовать по 5 товаров на каждой странице.Кроме того , категории должны быть упорядочены таким же образом , как они отображаются в меню слева ...моя схема БД выглядит следующим образом:

+-------------+    +-------------+
+ category    +    + product     +
+-------------+    +-------------+
+ category_id +    + product_id  +
+ parent_id   +    + category_id + 
+-------------+    +-------------+

Я действительно не могу понять, как я должен кодировать SQL, чтобы убедиться, что продукт отображается в том порядке, в котором он должен (например, в меню "Заказ продукта и категорий").

Также меня беспокоит производительность всей настройки, если пользователь выберет категорию, отличную от "конечной", мне пришлось бы выполнить поиск по всей дочерней категории и создать большую категорию В (id1, id2, id3), и я знаю по опыту, что оператор long IN работает плохо.

Если кто-то столкнулся с таким же дизайном / проблемой и у него есть несколько советов, как это сделать, я был бы благодарен.

Это было полезно?

Решение

Вы могли бы использовать Материализованный Путь Дизайн.Путь к каталогу - это пример материализованного пути.То есть ряд значений предка, объединенных вместе, с некоторым символом ("/" или "," являются общими), разделяющим их.

Таким образом, у вас могут быть категории:

+---------------------------------------------+
| cat_id | Name            | cat_path | depth |
+---------------------------------------------+
|    1   | Electronics     | 1/       |   1   |
|    2   | Digital cameras | 1/2/     |   2   |
|    3   | SLR cameras     | 1/2/3/   |   3   |
|    4   | Audio           | 1/4/     |   2   |
|    5   | Speakers        | 1/4/5/   |   3   |
|    6   | Wall Satellites | 1/4/5/6/ |   4   |
|    7   | Computers       | 1/7/     |   2   |
+---------------------------------------------+

Теперь, если вам нужны все продукты, которые находятся в разделе Audio, вы можете выполнить запрос типа:

SELECT p.*, pc.*
FROM Products p JOIN Categories pc ON (p.cat_id = pc.cat_id)
JOIN Categories c ON (pc.cat_path LIKE c.cat_path||'%')
WHERE c.name = 'Audio';

Например, '1/4/5/6' LIKE '1/4/%' это правда, поэтому настенные сателлиты включены в комплект поставки.И то же самое для любой другой подкатегории Аудио.


Повторяю ваш вопрос о рендеринге меню:Я предполагаю, что вы хотели бы, чтобы меню отображалось:- Все предки выбранной категории - Все братья и сестры предков выбранной категории

Итак, если вы выберете "Колонки", вы увидите:

  • Электроника
    • Аудио
      • Выступающие
    • Компьютеры
    • Цифровые Фотоаппараты

Но вам не нужны потомки Компьютеров или Цифровых камер (т.е."двоюродные братья" Говорящих).

SELECT uncle.name, uncle.depth
FROM Categories chosen
JOIN Categories ancestor ON (chosen.cat_path LIKE ancestor.cat_path||'%')
JOIN Categories uncle ON (ancestor.depth = uncle.depth
  AND SUBSTRING(REVERSE(ancestor.cat_path), 3, 100) = SUBSTRING(REVERSE(uncle.cat_path), 3, 100))
WHERE chosen.name = 'Speakers'
ORDER BY uncle.depth, uncle.name;

Я использую трюк, чтобы обнаружить дядюшек:сравните пути, предварительно удалив последний элемент.Чтобы сделать это, переверните нитку, а затем снимите Первый элемент.Это должно работать, по крайней мере, в MySQL и MS SQL Server, но REVERSE() не является стандартным и может быть непереносимым для других брендов СУБД.

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

Другие советы

С точки зрения производительности это плохой дизайн.Если клиент случайно нажмет на самую верхнюю категорию, вы выполните запрос всего вашего инвентаря.Вероятно, это займет недопустимо много времени.В терминах Интернета это означает, что клиент теряет терпение, переходит на сайт вашего конкурента и никогда больше не посещайте ваш сайт.

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

Я бы также не согласился со всей идеей древовидной навигации как подхода.Это немного попахивает тем, что вы просите своих клиентов поиграть в игру "Угадай, как мы проводим инвентаризацию наших запасов".Помимо всего прочего, во многих сферах продукт может принадлежать более чем к одной категории, поэтому выстраивание их в иерархию является произвольным процессом.По крайней мере, у вас, вероятно, должна быть модель данных, которая поддерживает отнесение продукта к нескольким конечным категориям.(Это может зависеть от характера того, что вы продаете, и детализации ваших категорий).

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

cat1 product1
cat1 product2
cat1 product3
cat1 product4
cat1 cat1.1 product1
cat1 cat1.1 product2
cat1 cat1.2 product3
cat1 cat1.2 product4
cat1 cat1.1 cat1.1.1 product1
cat1 cat1.1 cat1.1.2 product2
cat1 cat1.2 cat1.2.1 product3
cat1 cat1.2 cat1.2.2 product4

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top