![]() |
|
Модераторы: LSD |
![]()
|
|
| linuxoid |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 180 Регистрация: 17.4.2005 Репутация: нет Всего: нет |
Здравствуйте уважаемые коллеги!
У меня такая проблема: В таблице много записей. У каждой из них есть поле - pid (это id родителя, который так же находится в данной таблице). Обзовем каждую запись каталогом. У главных каталогов pid = 0, т.к. выше никого нет. Каталоги с pid=0 являются родителями для всех остальных каталогов (a.k.a. записей таблицы). Т.е. остальные каталоги - child'ы главных. Причем подкаталогов может быть сколь угодно много. Так вот... к примеру каталог с id = 100 будет содержать pid = 60 (т.е. это child каталога, у которого id = 60, и который находится в этой же таблице). В свою очередь каталог с id = 60 является child'ом каталока с id = 30 (т.к. pid = 30). У записи с id = 30 parent = 0. Т.е. мы дошли до главного каталога (pid = 0), а все предыдущие былы его child'ами. Получаем такой пройденный путь до главного каталога/parent'а: 100 -> 60 -> 30 -> 0. К примеру в php я могу написать рекурсивную ф-ию, которая будет до упора подниматься вверх от указанного id каталога и закладывать в массив встретившихся id. Получим путь. Из нашего примера это 100 -> 60 -> 30 -> 0. Т.е. мы поднялись к главному родителю и запомнили все промежуточные id. Далее можно использовать такую ф-ию для текущего пути на сайте и т.д. Вопрос такой: как реализовать проверку в SQL (работаю в PostgreSQL): я указываю parent'a. Нужно выбрать только те записи, которые являются подкаталогами указанного parent'a (к примеру указан id parent'a = 30). Значит когда будим проходить строку, где id = 100, мы увидим, что у этой строки pid = 60, а у этой строки (id = 60) pid = 30. Bingo. Значит данная строка является одним из подкаталогов, входящих в цепочку подразделов для указанного парента * Задача усложняется тем, что в одной таблице у меня известна только 1 величина: id в таблице каталогов. По этой известной величине (и значению parent'a, которое так же известно) я должен определить, приведет-ли меня этот id по pid к parent'у, который я указал... Если да, то эта запись из таблицы нам подходит, если нет - пропускаем её. Надеюсь вопрос понятно изложил. Жду с нетерпением какие-то подсказаньки и практические решения (если таковые имеются). Спасибо! |
|||
|
||||
| DimW |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1330 Регистрация: 24.2.2005 Где: Орёл Репутация: 2 Всего: 44 |
||||
|
||||
| linuxoid |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 180 Регистрация: 17.4.2005 Репутация: нет Всего: нет |
Благодарствую за информацию. Это хорошая зацепка, с помощью которой я нашел более удачный вариант - универсальный метод работы с иерархическими данными в рамках базы данных (метод с CONNECT BY все-таки не подходит, т.к. нужно патчить Postgres + мне скорее всего понадобится перебираться со всеми кодами на MySQL). В общем если кому интерестно, как обойти проблему работы с рекурсией вот ссылка: http://dev.e-taller.net/dbtree/ (чтобы разобраться почитайте 0599-1.pdf). Но на самом деле в случае с моей проблемой я сделал все проще (за счет чего мои запросы теперь ускорились в разы, т.к. я больше не смешиваю их с функциями PHP для рекурсии). Я просто создал для той самой таблицы другую вспомогательную таблицу - chain_nodes, в которой сделал поля id, ref_table_id (таблица, где я храню id каталога), node_id (перечисляем все id родителей). При добавлении новой записи я теперь просто записываю все узлы до главного каталога в специальную таблицу (chain_nodes), за счет чего удалось добиться хорошей скорости. Просто выбираю те записи, у которых поле id_каталога входит в подкаталоги каталога, который я укажу. Т.е. идет выборка из chain_nodes, где для такой-то записи фигурирует id главного каталога (проблем нет, т.к. я не обновляю и не перетаскиваю никуда эти подкаталоги. Т.е. они всегда на месте и id не меняются). Это сообщение отредактировал(а) linuxoid - 23.7.2009, 12:47 |
|||
|
||||
![]()
|
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | PostgreSQL | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |