MySQL, вложенность. определение конца
Задача следующая:
Есть таблица table
1 | 0 | name1
2 | 1 | name2
3 | 1 | name3
4 | 2 | name4
5 | 0 | name5
6 | 4 | name6
7 | 6 | name7
8 | 4 | name8
если to_id > 0 то эта строка пренадлежит строке to_id == id
/name1/name3/name5 вернет строку с id 3
/name1/name2/name4/name8 вернет строку с id 8
/name1/name2/name4 вернет строку с id 4
/name1/name2/name4/name9/name12/name34 вернет строку с id 4
жирным помечено то что не существует в базе и/или отсутствует связь
[COLOR="Red"]Собственно вопрос: как на MySQL реализовать это? на php циклом без проблем.[/COLOR]
Есть идеи? =)
На SQL без использования рекурсии/циклов это сделать нельзя. Соотвественно используя ХП с циклами/рекурсией.
"Определением конца" будет момент, когда запрос не вернет данных. Можно ввести понятие "уровня"(level id) и признака "первый/последний" элемент. Это ускорит и упростит запросы, но создаст другие проблемы.
Да. А что есть другие способы реализаций?)
Это реализация на php
$i=0;
$folder_parent=0;
// $this->url - масив урла
foreach($this->url as $url) {
if($folder=$_db->sel(PREFIX.'folder',array('folder_url'=>$url,'folder_state'=>'1','folder_parent'=>$folder_parent))) {
$folder_data=$folder;
$folder_parent=$folder_data['folder_id'];
$this->page_way[]=array($folder_data['folder_url'],$folder_data['folder_name'],'/');
$i++;
}
else
break;
}
if($folder_data) {
Зависит от ваших задач, мне, видя только структуру таблицы и не имея понятия о состояниях и концепции программы - сложно сказать - есть ли другие способы.
О варианте признака "первый/последний элемент" я уже упоминал. Если уровней вложенности может быть произвольно много - подобный признак имеет смысл ввести (опять же сугубо ИМХО - универсальных решений не существует). Так же стоит рассмотреть введение параметра level id.
По хранению деревьев в БД материала достаточно много, некоторые моменты из них обсуждались здесь например.
Иногда есть смысл в денормализации БД - т.е. способов действительно не мало.
Генерируем MySQL запрос
FROM folders AS t1
LEFT JOIN folders AS t2 ON t1.id = t2.to_id && t2.url = 'name2'
LEFT JOIN folders AS t3 ON t2.id = t3.to_id && t3.url = 'name4'
LEFT JOIN folders AS t4 ON t3.id = t4.to_id && t4.url = 'name9'
LEFT JOIN folders AS t5 ON t4.id = t5.to_id && t5.url = 'name12'
LEFT JOIN folders AS t6 ON t5.id = t6.to_id && t6.url = 'name34'
WHERE t1.url = 'name1' && t1.to_id = 0
[COLOR="Silver"]Запрос занял 0.0020 сек[/COLOR]
Получам
1 | 2 | 4 | NULL | NULL | NULL
И далее анализируем средствами php.
Вот только осталось проверить на быстродействие, быстрее это или цикл на php и кучу запросов?
ИМХО это. но надо проверить.)
А ето ниче что там джоинов вагон ???
Не факт что бистрее. Мерять надо.
А вообще щем генерить такие скли может лутше сторку написать и ей как параметр урлу дать??
Я с удовольствием. но нет идей. Ситуация следующая: урл только в виде ЧПУ. Далее идем, есть таблица folder с неограниченной вложенностью, далее таблица page могут быть как статические так и типа list, т.е. являются таблицей с неограниченной вложенности. получаем
/name1/name2/name4/ - это папки
name9 - это страница типа list
name12/name34 - это элементы страницы name9
всякие префиксы типа folder, page,... не приветствуется
:) Как нет. На РНР ведь реализовали. Так же только в сторке. Секономите на запросах к базе извне. Правда я не совсем знаю нюанси сторок в МуСКУЛе