Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

особенности MySQL запросов

537
30 марта 2004 года
Cover
87 / / 14.11.2002
У меня в базе хранится дерево категорий (неважно каких). Если категория вложенная в другую категорию, то у неё parentid=Идентификатор_Родительской_Категории. Если категория лежит "в корне", то parentid=0.

Однажды мне понадобилось собрать информацию о всех родительских категориях для текущей (ну типа определить путь от корня до текущей категории). Мне известен только идентификатор текущей категории. Долго думал, как мне такой лихой запрос составить. Не придумал, поэтому решил делать как положенно - т.е. в цикле выбирать родительские категории, пока не дойду до корня. Но всё делать на PHP мне не захотелось, поэтому я покопался в книжке по MySQL и нашёл там "переменные", с помощью которых всё и сделал.
Всё бы ничего, да только совершенно неожиданно я столкнулся с интересным явлением, который объяснить не смог. Может вы мне разъясните, что да как??

Вот запрос:

SET @prev_cat=CATEGORY_IDENTIFICATOR;
SELECT g.id AS cid,g.type,@prev_cat:=g.parentid AS parentid,g.name,g.gdescr FROM gds_tree g WHERE g.id=@prev_cat;

Он должен мне возвращать данные о категории с id=CATEGORY_IDENTIFICATOR и устанавливать @prev_cat в идентификатор "родительской" категории. Он так и делает, но только, если в таблице "gds_tree" более одной записи (ну т.е. категории) - всё работает нормально.
А вот если в таблице "gds_tree" ровно одна категория (т.е. запись), то этот запрос мне всегда возвращает эту запись, вне зависимости от того, что я подставляю в CATEGORY_IDENTIFICATOR. На практике это вылилось в зависание скрипта с линейным ростом требуемой памяти. А так как на работе админ зачем-то установил время выполнения PHP-скриптов !!5 МИНУТ!!, было очень весело сидеть и смотреть на красную лампочку (индикатор занятости винта) на серверном компе ;)
1.9K
30 марта 2004 года
HabaHaba
172 / / 24.12.2003
Ответить на вопрос, к сожалению, не смогу -- не сталкивался. Но вот хочу "посватать" метод хранения деревьев под названием nested sets (вложенные множества).
Способ прост и гениален. Получить всё дерево одним запросом -- не вопрос. И никакой рекурсии.
Лично я, давно уже отошел от рекурсивного хранения деревьев и пользую nested sets во всех задачах -- пока минусов не вижу.
В общем, всем искренне рекоммендую.
Ссылки по теме:
По русски с картинками
PEAR класс для работы с n.s. -- очень удобный
537
30 марта 2004 года
Cover
87 / / 14.11.2002


Сэнкс за линки.
Вот до чего доводят всякие хтмлы и языки высокого уровня - до полной деградации программистов. Совсем я чё-то про оптимизацию забыл. Так скоро заного в школу идти придётся :)

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

Вобщем есть над чем подумать.
Может я скоро новый способ хранения дерева в БД придумаю ;)

1.9K
31 марта 2004 года
HabaHaba
172 / / 24.12.2003
Цитата:
Originally posted by Cover
.....
Кстати в этом методе "Nested Set" есть один большой минус - это добавление новых данных или изменение структуры. Конечно в большинстве случаев (и в моём тоже) добавление происходит довольно редко. Но вот если придётся писать какую ни будь "барахолку", где и структура изменяемая и данные каждый юзер может добавлять, вот там начнётся боольшааяя тормозуха.
...


Ну... Если немножко поDOOMать, обходится это дело совершенно без "тормозух" :)
Скажем так, для каждого трэда, как бы начинать новую "вершину" и работать только от неё. Тогда апдэйтить придется только 1 ветку а не всё дерево.
Кстати, в одном проекте по управлению контентом, мне нужно было решить задачу хранения сложной структуры документа. Так вот я там использовал n.s. заводя по "вершине" для каждого документа. Работало влёт, реализовывалось просто, а документ, при этом, получал абсолютно ничем не огранинченую структуру.
Кстати, ещё один как бы совет.
Если у тебя сильно ветвистая структура, имеет смысл отдельно хранить дерево в полностью проиндексированной таблице с одними интами а контент разнести в другие таблицы и цеплять их по мере надобности. Тогда ещё шустрее работает.
В PEAR так и сделано по моему.
Да и вообще... С веб проектами содержашими более полумиллиона записей в бд мне приходилось сталкиваться всего пару раз за всю свою практику. А на меньших объёмах затормозить базу можно только очень-очень кривыми лапками :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог