Модераторы: skyboy, MoLeX, Aliance, ksnk

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Мультикатегории и подсчёт данных в них 
:(
    Опции темы
Serious2008
Дата 26.3.2012, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 28.1.2011

Репутация: нет
Всего: нет



Здравствуйте у меня возникла вот такая ситуация. 
Есть допустим продукт, он может быть расположен в множестве категорий. Чтобы сильно не мудрить я решил хранить в записи товара вот так /№ категории/№ другой категории/№ третьей категории/
И вприципе выборка из категории отлично происходит при помощи in ('/id_kat/'). Но вот возникла проблема. Мне нужно посчитать количество товаров в категориях. И категории многоуровневые. Т.е. мне нужно как-то проходиться по всем детям родительской категории и посчитать товары.
Т.е. 
Родительская категория (N) 
 - Ребёнок 1(X)
 ---Ребёнок ребёнка (YX)
 - Ребёнок 2(X2)
 .....
 - Ребёнок N(XN)

И вложенность бесконечная. А Число N должно быть суммой всех ребёноков. И товары могут располагаться только в конечной категории. В скобках число.
PM MAIL   Вверх
skyboy
Дата 26.3.2012, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 14
Всего: 260



в самой категории хранить счетчик "товаров в категории". триггером при измении категории у товара делать перерасчет. единственное нетривиальное место: как в триггере, имея старый и новый списки категорий продукта(/1/5/10/12/ и /1/5/11/12/) найти отличие. после нахождения уже не так сложно будет smile
PM MAIL   Вверх
ksnk
Дата 27.3.2012, 07:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(Serious2008 @  26.3.2012,  23:28 Найти цитируемый пост)
И вприципе выборка из категории отлично происходит при помощи in ('/id_kat/')


Цитата(Serious2008 @  26.3.2012,  23:28 Найти цитируемый пост)
посчитать количество товаров в категориях

Если выборка делается просто, то и посчитать количество результатов выборки тоже просто. Нет?


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
baldina
Дата 27.3.2012, 10:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Цитата(ksnk @  27.3.2012,  07:58 Найти цитируемый пост)
Если выборка делается просто, то и посчитать количество результатов выборки тоже просто. Нет? 

видимо выборка по одной категории, а подсчет по иерархии
PM MAIL   Вверх
Serious2008
Дата 27.3.2012, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 28.1.2011

Репутация: нет
Всего: нет



ksnk, 
Да-да-да именно про иерархичный подсчёт я и говорю.
PM MAIL   Вверх
baldina
Дата 27.3.2012, 10:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



если строка /1/2/3/ означает, что категория 3 входит в категорию 2 и т.д., то для требуемого подсчета нужно знать, кто у данной категории родитель (до самого корня). тогда, например, если нужно подсчитать число товаров в категории 3 и потомках условие запроса будет
Код

LIKE "/1/2/3/%"

а для числа товаров в категории 1
Код

LIKE "/1/%"


Это сообщение отредактировал(а) baldina - 27.3.2012, 10:54
PM MAIL   Вверх
Serious2008
Дата 27.3.2012, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 28.1.2011

Репутация: нет
Всего: нет



baldina, 
Нет просто означает в какую категорию входит. Так бы я тоже догадался выбирать по первому из запроса.
PM MAIL   Вверх
baldina
Дата 27.3.2012, 11:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



ну раз так, то
Цитата(Serious2008 @  26.3.2012,  23:28 Найти цитируемый пост)
Чтобы сильно не мудрить

не мудрое решение))
надо мудрить

PM MAIL   Вверх
ksnk
Дата 27.3.2012, 11:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(Serious2008 @  26.3.2012,  23:28 Найти цитируемый пост)
 он может быть расположен в множестве категорий. Чтобы сильно не мудрить я решил хранить в записи товара вот так /№ категории/№ другой категории/№ третьей категории/

Это значит, что товар находится в разных категориях. не связанных друг с другом?

Каким образом задается дерево категорий?



--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Serious2008
Дата 27.3.2012, 12:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 28.1.2011

Репутация: нет
Всего: нет



ksnk, 
да в разных категориях не завязанных никак между собой, только через 0 она корень.
Дерево через id и parent_id
Т.е. все категории именно вот так. Каждая категория имеет родительского. Те которые корни, они 0. 
Т.е. там может быть допстим так.

Электрооборудование - лобзики
Электрооборудование - инструменты - рабочий инструмент
Рабочий инструмент2 - Инструменты.

И товар может находиться только в каждой конечной.
Т.е. получается в электрооборудовании будет 2 товара типа. в лобзиках 1, в рабочем инструменте 1.
Во втором родителе один товар и в Инструментах 1 тоже.

PM MAIL   Вверх
baldina
Дата 27.3.2012, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Цитата(Serious2008 @  27.3.2012,  12:38 Найти цитируемый пост)
Дерево через id и parent_id

1. иерархические запросы на sql, специфично для ЯБД. пример для mysql тут
2. если количество товаров не слишком велико, можно загрузить их в массив и обработать на php
PM MAIL   Вверх
Fortop
Дата 27.3.2012, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(Serious2008 @  26.3.2012,  23:28 Найти цитируемый пост)
 Чтобы сильно не мудрить я решил хранить в записи товара вот так /№ категории/№ другой категории/№ третьей категории/

Фиговое решение :( выполните нормализацию искать и считать станет проще.

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



--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
Serious2008
Дата 27.3.2012, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 28.1.2011

Репутация: нет
Всего: нет



Fortop, 
Предложите лушчий вариант, сказать что фиговое решение любой может.
PM MAIL   Вверх
Fortop
Дата 27.3.2012, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Serious2008, я вам уже предложил.
Храните категории отдельно.
Или nested sets или почитайте это http://demiurg.livejournal.com/53125.html
http://mikehillyer.com/articles/managing-h...-data-in-mysql/

materialized path если очень уж сильно нужен зачем-то - оставьте, но помните что обновлять надо будет в нескольких местах.

Добавлено через 2 минуты и 7 секунд
Ах, да, у вас же даже не MP

тогда тупо нормализуйте БД

Заведите таблицу отношений
Товар-Категория

и делайте выборку по ней.


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
ksnk
Дата 27.3.2012, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Итого, для категории X нужно найти все подкатегории и суммировать количество товаров в них.
Все подкатегории категории X вычисляем рекурсивно, чем-то вроде
Код

select id from `categories` where parent=X;

Находя всех чилдов, у каждого чилда - своих чилдов и так далее... Сильно оптимизировать, при такой структуре данных не получится. При желании - список подкатегорий можно хранить в самом узле, пересчитывая его по мере изменения.

Получается список всех чилдов узла.

Запрос, вычисляющий количество товаров в категории - 
Код

select count(*) from `items`where `categories` like '/cat1/' or `categories` like '/cat2/' or ... для всех чилдов.


Надо бы смотреть в сторону nested sets, для хранения дерева категорий. Там задача вычисления чилдов решается в один простой запрос.
Сами категории товара хранить в отдельной таблице. {id товара; id категории}

Хотя сначала надо сделать систему кэширования результатов подсчета, так как эффективная схема хранения данных все равно от этого не спасет.


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
Fortop
Дата 27.3.2012, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Цитата(ksnk @  27.3.2012,  14:41 Найти цитируемый пост)
Хотя сначала надо сделать систему кэширования результатов подсчета, так как эффективная схема хранения данных все равно от этого не спасет. 

Куда с кешированием-то торопится?
ТС не указал даже как часто ему это надо вычислять smile


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
ksnk
Дата 27.3.2012, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 14
Всего: 386



Цитата(Fortop @  27.3.2012,  14:46 Найти цитируемый пост)
ТС не указал даже как часто ему это надо вычислять

Эти числа, imho, должны появляться при любом выводе таблицы категорий. То есть - часто ;), на каждой странице с товаром.
Вычисленные значения, вероятно, удобнее хранить прямо в таблице категорий


--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
baldina
Дата 27.3.2012, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Цитата(ksnk @  27.3.2012,  14:41 Найти цитируемый пост)
Надо бы смотреть в сторону nested sets, для хранения дерева категорий. Там задача вычисления чилдов решается в один простой запрос

зато задача добавления не в один))

PM MAIL   Вверх
skyboy
Дата 27.3.2012, 22:20 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 14
Всего: 260



Цитата(ksnk @  27.3.2012,  13:57 Найти цитируемый пост)
Вычисленные значения, вероятно, удобнее хранить прямо в таблице категорий 

Цитата(skyboy @  26.3.2012,  22:59 Найти цитируемый пост)
в самой категории хранить счетчик "товаров в категории". 

попытка номер два.
PM MAIL   Вверх
Serious2008
Дата 29.3.2012, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 294
Регистрация: 28.1.2011

Репутация: нет
Всего: нет



Снова здравствуйте.

Вот у меня где загвоздка, правда прошу помощи, причём желательно в виде кода.
Первый массив, это все категории где могут быть данные, например товары. Мне нужно посчитать, сколько этих товаров содержится во всех категориях по выше стоящему, второй массив это как бы древо, в котором содержатся ветки. Т.е. 0 это корень, от неого отходят 1,3,5,6,7,8. Потом от 1 отходит 2,4, от 2 отходит 10 и ещё от 5 отходит 9. Предположим что в 10 у нас один товар, а в 4-ом 3. то тогда в 1-ом должно получиться 4 по простой логике, но дело в том, что там может один и тот же товар быть и в 4-ой и в 10-ой категории. И тогда в 1 у нас должо получиться 3 товара. А если и в 9-ом тоже один какой-нибудь товар хранящийся в 4, то тогда в 0 должно получится тоже 3 товара. Но допустим в 0 можно пихать все товары и тут как бы не сложно посчитать. А вот как быть с детьми я не знаю. Ниже пример массивов
Код


Array
(
    [0] => 10
    [1] => 4
    [2] => 3
    [3] => 9
    [4] => 6
    [5] => 7
    [6] => 8
)
Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 3
            [2] => 5
            [3] => 6
            [4] => 7
            [5] => 8
        )

    [1] => Array
        (
            [0] => 2
            [1] => 4
        )

    [2] => Array
        (
            [0] => 10
        )

    [5] => Array
        (
            [0] => 9
        )

)

PM MAIL   Вверх
Fortop
Дата 30.3.2012, 07:41 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Serious2008, для каждой категории выберите список ее детей (всех) и дальше делайте агрегацию запросом

т.е. будет что-то вида

Код

select sum(item_count) from item_list where item_list.id IN (
    SELECT id FROM item_in_cat WHERE item_in_cat.cat_id IN (тут список всех детей вашей категории))


Это сообщение отредактировал(а) Fortop - 30.3.2012, 07:41


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
baldina
Дата 1.4.2012, 19:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 2
Всего: 101



Serious2008, Вам нужно обойти дерево (поиск в глубину, рекурсивно). Каждому элементу массива (узлу дерева) ставите в соответствие число товаров. При покидании узла 
1. если этот узел слдержит товар - присваиваете числу товаров 1
2. прибавляете к числу товаров сумму товаров поддеревьев
попробуйте сами, не получится - поможем с кодом
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0666 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.