Форум → Разработка → Базы данных → Принцип работы nested sets
Принцип работы nested sets
Страницы: ← Следующая страница →
-
Решил ради интереса посмотреть принцип работы сия чуда. С виду всё красиво хотя и замудрено до жути.
Но вот возник у меня один вопрос. Как получить все данные именно выбранного раздела?
Допустим у нас есть дерево такого вида:
a - b - c (основной раздел - подраздел - под-подраздел)
d - b - c (второе древо и т.д.)
В итоге в адресной строке будем иметь следующее:
mysite.ru/a/b/c/ и mysite.ru/d/b/c/
Как извлечь из таблицы данные нужные нам, ведь фактически имя раздела и подраздела одинаковые, разные у них только корневые разделы. Неужели придется идти от начала древа и до конца? Но тогда теряется весь смысл этого самого nested sets. Объясните пожалуйста где я туплю и чего я не понимаю?
А конечная задача сделать возможность добавлять бесконечное множество вложений и чтоб имена этих самых вложений могли совпадать. Ведь по большому счету можно сделать ссылку типа mysite.ru/a/a/a/a/a/a/a/a/… И вот как в такой схеме вычислять конкретный элемент?
PS. Надеюсь мысль мою вы поняли :) Если нет, то спрашивайте, я объясню подробнее :)from TRIAL with LOVE -
12 сентября 2012 г. 14:40, спустя 46 минут 20 секунд
И вот как в такой схеме вычислять конкретный элемент?
а зачем тебе конкретный?
последний крайний да и все.
а от него уже получить и корневые и детейСапожник без сапог -
12 сентября 2012 г. 14:49, спустя 8 минут 27 секунд
Ну это же одним запросом к БД не обойдется или я не прав? У меня щас все строится по схеме id, sub_id, соответственно всё дерево рисуется рекурсивной функцией и уж сколько там запросов к БД идет не знаю, но явно не мало, пускай и происходит это всё без единой задержки. Я то искал способ чтобы обращаться к БД всего 1 раз и получать все данные.
Пока на обед ходил, мысль пришла при первой загрузке сайта создавать массив из всех эл-тов дерева и записывать всё это в сессию чтобы в дальнейшем только к ней обращаться. Наверное должно это выглядеть как-то так $_SESSION['site_tree'][a][a][a][a][a][a] или как-то так. В общем чертить путь внутри многомерного массива чтоб в конечном итоге получить id нужного нам раздела.
Не знаю на сколько эта идея нормальна правда… )))from TRIAL with LOVE -
-
12 сентября 2012 г. 15:15, спустя 16 минут 37 секунд
Думал и такое сделать но чет не очень привлекает.
Если имя раздела изменится, нужно будет по всей базе проходится и заменять данные. Тоже не айс. Всё еще склоняюсь к древу в сесии. Хотя вот народ пишет что не самое хорошее решение разный мусор в сессии хранить. Думал может какой кэш использовать или еще чего, но никогда с таким дел не имел.from TRIAL with LOVE -
12 сентября 2012 г. 15:21, спустя 5 минут 35 секунд
нет, если имя меняется - по всей базе не нужно бегать. Только если родитель, и то не совсем по всейСпустя 227 сек.и ваще у меня вот доктрина2 с соответствующим плагином. Она сама занимается поддержкой структуры данных -
12 сентября 2012 г. 16:27, спустя 1 час 6 минут 31 секунду
а у нас в квартире газ
нет, если имя меняется - по всей базе не нужно бегать. Только если родитель, и то не совсем по всейСпустя 227 сек.и ваще у меня вот доктрина2 с соответствующим плагином. Она сама занимается поддержкой структуры данныхСпустя 4 сек.если вы знаете что это такое :D:D:DСапожник без сапог -
12 сентября 2012 г. 17:31, спустя 1 час 3 минуты 20 секунд
Пишу сейчас цмс. Сам вожусь с nested sets:
Почему не a-b-c и d-e-f и site.ru/a, site.ru/b, site.ru/c, site.ru/d, site.ru/e, site.ru/f ? 1 запрос и все хлебные крошки в нём
Решил ради интереса посмотреть принцип работы сия чуда. С виду всё красиво хотя и замудрено до жути.
Но вот возник у меня один вопрос. Как получить все данные именно выбранного раздела?
Допустим у нас есть дерево такого вида:
a - b - c (основной раздел - подраздел - под-подраздел)
d - b - c (второе древо и т.д.)
В итоге в адресной строке будем иметь следующее:
mysite.ru/a/b/c/ и mysite.ru/d/b/c/
Как извлечь из таблицы данные нужные нам, ведь фактически имя раздела и подраздела одинаковые, разные у них только корневые разделы. Неужели придется идти от начала древа и до конца? Но тогда теряется весь смысл этого самого nested sets. Объясните пожалуйста где я туплю и чего я не понимаю?
А конечная задача сделать возможность добавлять бесконечное множество вложений и чтоб имена этих самых вложений могли совпадать. Ведь по большому счету можно сделать ссылку типа mysite.ru/a/a/a/a/a/a/a/a/… И вот как в такой схеме вычислять конкретный элемент?
PS. Надеюсь мысль мою вы поняли :) Если нет, то спрашивайте, я объясню подробнее :)
Ой да ну - ты постоянно про неё говоришь, как будто бы доктрина = панацея. Не только она умеет работать с деревьями official&client=firefox-a">https://www.google.com.ua/search?q=php+nested+sets+class&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla
нет, если имя меняется - по всей базе не нужно бегать. Только если родитель, и то не совсем по всейСпустя 227 сек.и ваще у меня вот доктрина2 с соответствующим плагином. Она сама занимается поддержкой структуры данныхofficial&client=firefox-a
-
12 сентября 2012 г. 17:38, спустя 7 минут 26 секунд
вообще если для контента - то phpcr с разными бекендами http://phpcr.github.com/ -
14 сентября 2012 г. 15:22, спустя 1 день 21 час 43 минуты
В общем что получилось в конечном итоге:
Структура БД
+—————+———————–+——+——–+—————+———————-+
| Field | Type | Null | Key | Default | Extra |
+—————+———————–+——+——–+—————+———————-+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| sub | int(11) | YES | | 0 | |
| vname | varchar(30) | YES | | NULL | |
+—————+———————–+——+——–+—————+———————-+
Скрипт:// URL
$a = array();
$n = 0;
// Создаем массив с древом сайта
$res = mysql_query("SELECT `id`, `sub`, `name`, `vname` FROM `main_table` ORDER BY `number`, `id`");
while($row = mysql_fetch_assoc($res)) {
if(empty($a[$row['sub']]))
$a[$row['sub']]=array();
$a[$row['sub']][]=$row;
}
// Разбивка url'а
$url_arr = explode("/", $_GET['dir']);
// Проверяем есть ли доп. параметры в последнем элементе массива (пример: /?id=xxx&atr=abc)
if(substr($url_arr[count($url_arr)-1], 0, 1) == "?") {
$tmp_arr_ext = substr($url_arr[count($url_arr)-1], 1);
$tmp_arr_ext = explode("&", $tmp_arr_ext);
foreach($tmp_arr_ext as $k => $v) {
$a = explode("=", $v);
$url_arr_ext[$a[0]] = $a[1];
}
}
//
$dir = array_slice($url_arr, 0, -1);
$c_dir = count($dir);
// Функция определения текущего id страницы
function tree_id_search(&$a,$sub=0,$count=0) {
if(empty($a[$sub])) return;
global $dir, $c_dir, $n, $cur_dir_id; // уровень вложения
$msr = count($a[$sub]);
// Если есть вложение
if($sub != 0) {
$n++;
for($i=0;$i<$msr;$i++) {
if($a[$sub][$i]['name'] == $dir[$n] && $n == ($c_dir-1)) { $cur_dir_id = $a[$sub][$i]['id']; break; }
tree_id_search($a,$a[$sub][$i]['id'],$msr);
}
$n–;
}
else {
$n = 0;
for($i=0;$i<count($a[$sub]);$i++) {
tree_id_search($a,$a[$sub][$i]['id'],$msr);
}
}
}
// Вычисляем ID текущего раздела
tree_id_search($a);
Ну вот как-то так.
По хорошему осталось еще оптимизировать функцию.
Как итог - имеем всего 1 запрос к БД. Причем если занести массив древа сайта в сессию, то сокращаем обращение к базе за поиском id раздела до одного (при первом заходе) на всё время лазания по сайту.
PS. Конечно вариант не идеальный, но посмотрим как покажет себя в будущих проектах.from TRIAL with LOVE -
14 сентября 2012 г. 15:44, спустя 21 минуту 51 секунду
TRIAL, Просто блять охуетительно, а сайт рости не будет? а если 10000 страничек будет? -
14 сентября 2012 г. 15:51, спустя 7 минут 38 секунд
Ну смотря что страницами считать. Если есть лента новостная и там 10 000 новостей по то сути страница то одна в которую передаешь какой-нибудь news_id. Хотя если реально страниц будет столько, моя схема не то что загнется, но будет работать весьма долго.
Я же не говорю что вариант идеальный. Хотя не пойму чем тот же nested sets лучше будет. Тут конечно всё от глубины вложения зависит. Навряд ли она будет больше 5-10, тогда проще реально сделать несколько запросов в базу чем прогонять каждый раз весь массив в поисках нужного ключа. В общем буду думать дальше и искать золотую середину.from TRIAL with LOVE -
14 сентября 2012 г. 16:00, спустя 9 минут
Что-то совсем не хочется мне url'ы в базу вносить. Не знаю почему конечно, но как-то чем-то смущает. С другой стороны конечно это резко упрощает всю работу и реально не надо заниматься таким онанизмом как у меня. Пожалуй я всё таки рассмотрю твой вариант.from TRIAL with LOVE -
14 сентября 2012 г. 16:59, спустя 58 минут 36 секунд
Глубина вложения ни о чём не говорит, если она будет 5 то в ширину может быть 10000, если понял о чём я. А вообще в чём проблемы то у тебя с нестед сетс? 1 запрос делает всё
Ну смотря что страницами считать. Если есть лента новостная и там 10 000 новостей по то сути страница то одна в которую передаешь какой-нибудь news_id. Хотя если реально страниц будет столько, моя схема не то что загнется, но будет работать весьма долго.
Я же не говорю что вариант идеальный. Хотя не пойму чем тот же nested sets лучше будет. Тут конечно всё от глубины вложения зависит. Навряд ли она будет больше 5-10, тогда проще реально сделать несколько запросов в базу чем прогонять каждый раз весь массив в поисках нужного ключа. В общем буду думать дальше и искать золотую середину. -
14 сентября 2012 г. 17:58, спустя 59 минут 36 секунд
некашерно выглядит
то есть по твоему кашерно, Абрам
Страницы: ← Следующая страница →
Пожалуйста, авторизуйтесь, чтобы написать комментарий!