[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Бесконечная вложенность категорий
Семён
Задача: Бесконечная вложенность категорий PHP + MySQL

Сегодня целый день ломаю голову над вопросом: "как?"
---
Имею структуру таблицы:
user posted image

Из рисунка видно, что id_cat, это под категория - категории с id_self
Дополнительно показал что есть что.

Вопрос как получить массив всего этого? (главное условие бесконечная вложенность)
Делать рекурсию с кучей запросов - имхо глупо.

Результат должен быть на выходе:

Категория - 1:
-Подкатегория:
-- Подкатегория:
--- Подкатегория:
---- Подкатегория
------ ...............
Категория - 2:
-Подкатегория:
-- Подкатегория:
--- Подкатегория:
---- Подкатегория
------ ...............


Прошу помочь.



Спустя 24 минуты, 15 секунд (23.12.2009 - 15:30) Семён написал(а):
Эксперты я надеюсь на Вас smile.gif

Спустя 6 минут, 8 секунд (23.12.2009 - 15:36) glock18 написал(а):
Семён
наводящий вопрос:
в меню войдет вся таблица, если не брать порядок и вложенность?

Спустя 1 минута, 46 секунд (23.12.2009 - 15:38) TMake написал(а):
Рекурсия тебе в помощь.

Спустя 2 минуты, 14 секунд (23.12.2009 - 15:40) Семён написал(а):
Glock
Для примера пускай берутся абсолютно все данные из таблицы. т.е. на выходе хотелось бы увидеть примерно такое:

[0] Категория
--------[0][0] Подкатегория
----------------[0][0][1] Подкатегория
----------------[0][0][2] Подкатегория
----------------[0][0][n] ....................
--------------------------------[0][0][n][n] ....................
--------------------------------[0][0][n][n] ....................
--------------------------------[0][0][n][n] ....................
--------[0][1] Подкатегория</span>

Спустя 1 минута, 11 секунд (23.12.2009 - 15:41) Семён написал(а):
Цитата (stepan @ 23.12.2009 - 16:38)
Рекурсия тебе в помощь.

Читай внимательно текст сообщения.
Также не стоит писать сообщения, если сам это ни разу не делал.

Спустя 10 минут (23.12.2009 - 15:51) glock18 написал(а):
Семён
тогда самое простое - выбираешь одним запросом все это, и проходишь по этому массиву, расставляя все в нужном порядке.

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

Спустя 1 минута, 16 секунд (23.12.2009 - 15:53) Семён написал(а):
Цитата (glock18 @ 23.12.2009 - 16:51)
Семён
тогда самое простое - выбираешь одним запросом все это, и проходишь по этому массиву, расставляя все в нужном порядке.

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

Хех. glock был бы тебе благодарен если дал бы подсказку )

Спустя 11 минут, 32 секунды (23.12.2009 - 16:04) Семён написал(а):
Нашёл велосипед. http://www.getinfo.ru/article610.html

Спустя 9 минут, 35 секунд (23.12.2009 - 16:14) glock18 написал(а):
Нашел здесь
http://phpforum.ru/index.php?act=Print&cli...imin=28&limit=1

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

если выбирать все одним запросом, то это элементарно заменяет все, что выше строк

echo '<pre>Fetched users';
print_r($fetchedUsers);
echo '</pre>';


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

в общем, смотри.

Спустя 5 минут, 47 секунд (23.12.2009 - 16:20) Семён написал(а):
glock18 - чувак я тебя люблю!

Спустя 18 минут, 43 секунды (23.12.2009 - 16:38) Семён написал(а):
Теперь попробую NESTED SETS, посмотрим, что круче )

Спустя 4 минуты, 2 секунды (23.12.2009 - 16:42) VolCh написал(а):
Nested sets шустро выбирает, но вот удаление, вставка и прочая модификация - ужас

Спустя 5 минут, 32 секунды (23.12.2009 - 16:48) Семён написал(а):
Цитата (VolCh @ 23.12.2009 - 17:42)
Nested sets шустро выбирает, но вот удаление, вставка и прочая модификация - ужас

на форуме каком-то вычитал? biggrin.gif

Спустя 5 минут, 29 секунд (23.12.2009 - 16:53) VolCh написал(а):
Опыт работы с БД >10 лет, правда не из под PHP и не на мускуле

Спустя 7 минут, 21 секунда (23.12.2009 - 17:01) glock18 написал(а):
да, со вставкой явные проблемы. для того чтобы понять 10-летнего опыта не надо )) хотя выборка действительно делается простая. однако структура таблицы такая, что вставка одного узла заставляет обновлять большую часть записей. в добавок ко всему, нужно вычислять каждый раз три параметра - уровень, левый и правый ключ.

Спустя 7 минут, 42 секунды (23.12.2009 - 17:08) TMake написал(а):
Цитата (Семён @ 23.12.2009 - 12:41)
Читай внимательно текст сообщения.

Текст я читал
Цитата (Семён @ 23.12.2009 - 12:41)
Также не стоит писать сообщения, если сам это ни разу не делал.

Ну ты тип решил посраться выставить себя умным, я то делал менюшку с неограниченными под меню, но из-за твоего отношения шлю тебя в игнор.

Спустя 1 час, 32 минуты, 29 секунд (23.12.2009 - 18:41) Семён написал(а):
Цитата (stepan @ 23.12.2009 - 18:08)
Цитата (Семён @ 23.12.2009 - 12:41)
Читай внимательно текст сообщения.

Текст я читал
Цитата (Семён @ 23.12.2009 - 12:41)
Также не стоит писать сообщения, если сам это ни разу не делал.

Ну ты тип решил посраться выставить себя умным, я то делал менюшку с неограниченными под меню, но из-за твоего отношения шлю тебя в игнор.

1) to Stepan, Я с тобой не срался, просто не нада было показывать, что ты умник. Я прекрасно знаю силу твоих способностей, что и как ты можешь сделать. Если не умеешь читать, но научился умничать и отвечать как "человек - загадка, бабка гадалка' - это твои проблемы, нытик блин. cool.gif
2) to VolCh, на счёт форума - пошутил, а то может не понял, на форумах просто про этот метод идут обширные холивары smile.gif
3) to glock - тебе за помощь спасибо огромное, освободил мой мозг.

Спустя 6 минут, 56 секунд (23.12.2009 - 18:48) HardWoman написал(а):
Цитата
на форуме каком-то вычитал? biggrin.gif


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

Есть конечно вариант с дырками ID, но и там при частом редактировании лимит выбрать можно

Спустя 1 час, 43 минуты, 3 секунды (23.12.2009 - 20:31) Soldier Ghost написал(а):
Есть тут такая тема я её создавал тоже нужно было такое осуществить там два варианта решения поищи тут.

Спустя 13 часов, 16 минут, 41 секунда (24.12.2009 - 09:48) Семён написал(а):
Тема закрыта.
На 1-ой странице glock - дал имхо самое лучшее решение этой задачи, на момент того, что я сам делал и делали другие.

Спустя 23 минуты, 22 секунды (24.12.2009 - 10:11) TMake написал(а):
Цитата (Семён @ 23.12.2009 - 15:41)
Я прекрасно знаю силу твоих способностей

Отлично успокоил ( ненавижу людей которые говорят так, когда на самом деле совсем не знают человека ), извини но мы с тобой на брудершафт не пили tongue.gif
Цитата (Семён @ 23.12.2009 - 15:41)
не нада было показывать, что ты умник.

Ты мне еще и рамки будешь ставить, в игнор тебя! laugh.gif

Спустя 5 минут, 1 секунда (24.12.2009 - 10:16) sergeiss написал(а):
stepan!

Твои слова - флуд в тематическом разделе. Если что-то не нравится, то есть раздел для болтологии, есть личная почта.
Это нечто типа предупреждения. На всякий случай...

Спустя 7 минут, 1 секунда (24.12.2009 - 10:23) Семён написал(а):
Вот изменил для выборки из базы, пока оставлю так, может что изменю.
Имхо новичкам / да и продвинутым должно пригодиться, всегда избегал вложенность.
Order / Case не стал упрощать, т.к. найду им применения позже wink.gif

$result = $core->database->select("SELECT * FROM ?_shopcats");
for($i=0; $i<count($result); $i++)
{
$cats[$result[$i]['id']]['id'] = $result[$i]['id'];
$cats[$result[$i]['id']]['parentId'] = $result[$i]['parentId'];
$cats[$result[$i]['id']]['cat_title'] = $result[$i]['cat_title'];
}

$fetchedUsers = array();
function doQuery($ids, $order = 1,$cats = NULL)
{
switch ($order)
{ case 1: return $cats; }
}

$order = 1;
$users = doQuery($userId, $order,$cats);
do {
$idsToFetch = array();
if (is_array($users))
{
$idsToFetch = array_diff_key($users, $fetchedUsers);
if (empty($idsToFetch))
break;

$fetchedUsers += $users;
$users = doQuery($idsToFetch, ++$order,$cats);
}
}
while (!empty($idsToFetch));

$tree = array();
foreach($fetchedUsers as $id => &$user)
{
if ($user['parentId'] == 0)
$tree[$id] =& $user;
else
$fetchedUsers[$user['parentId']]['items'][$id] =& $user;
}
unset($fetchedUsers);

echo '<pre>Tree';
print_r($tree);
echo '</pre>';

Спустя 2 дня, 4 часа, 5 минут, 19 секунд (26.12.2009 - 14:28) -Kein- написал(а):
+1 за Nested Sets, хорошая вещь, я этот метод использую.
А вот еще статья интересная: http://www.rsdn.ru/article/db/Hierarchy.xml

UPD: Еще можно организовать с базовой структурой (ID, name, parentID), если делать вложенный запросы не в пхп(10-20 вложенности, и время работы подскочит), а через скл, правда я сам с этим не знаком, и не пробовал, но как мне говорил знакомый, такой метод приемлем, если возвращать уже подготовленный массив в пхп.

Спустя 11 месяцев, 14 дней, 5 часов, 47 минут, 10 секунд (10.12.2010 - 20:15) Guest написал(а):
Хм... на тему рекурсии читал, но всё же:

<?
function
testparent ($id,$tabs) {
$tabs = $tabs."--- ";
$sql = "SELECT * FROM menuv2 WHERE parent='$id'";
$result = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
menuv2($row['id'],$tabs);
};
};

function menuv2($parent,$tabs) {
//$tabs = $tabs."--- ";
$sql = "SELECT * FROM menuv2 WHERE id='$parent'";
$result = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
echo ($tabs.$row['name']."<br>");
testparent ($row['id'],$tabs);
}
}
;

// $tabs = "---";
$sql = "SELECT * FROM menuv2 WHERE parent=''";
$result = mysql_query($sql) or die(mysql_error());
while ($row = mysql_fetch_assoc($result)) {
menuv2($row['id'],$tabs);
};

?>


смотрел на нагрузку на сервер - херня, не так уж и сильно
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.