ECommerce, продукты по категориям и категориям - PullRequest
1 голос
/ 29 октября 2009

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

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

Пользователь может просматривать любую категорию, даже не "листовую" категорию, если пользователь щелкает по неконечной категории список, подобный тому, который должен быть представлен для примера в категории уровня 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, чтобы убедиться, что товар отображается в том порядке, в котором он должен (например, в меню заказа товаров и категорий).

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

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

Ответы [ 2 ]

6 голосов
/ 29 октября 2009

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

Так что вы можете иметь категории:

+---------------------------------------------+
| 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   |
+---------------------------------------------+

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

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;

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

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

1 голос
/ 29 октября 2009

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

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

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

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

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

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

...