|
|
|
| Допустим имеется таблица вида:
ID | Parent ID | Name
+ | INT | CHAR
|
Данные представляют собой древовидную структуру, и Parent ID ссылается на ID родительской записи:
0 | -1 | root
1 | 0 | doc
2 | 0 | tmp
3 | 1 | tests
|
здесь в каталге root лежат каталоги doc и tmp, а в каталоге doc лежит tests:
root/doc
root/doc/tests
root/tmp
|
Вопрос: как мне в выборке показывать полные пути, как в последнем примере (соединены символом '/'), и возможно ли вести поиск по получившимся строкам (например поиск 'root/doc', т.е. поиск каталога doc в каталоге root) ? | |
|
|
|
|
|
|
|
для: Wyfinger
(21.07.2007 в 15:29)
| | Такие вещи лучше делать на уровне приложения (средствами php).
Для преобразования в реальный путь на лету средствами SQL методика хранения деревьев adjacency lists подходит слабо. Если это требуется железно, лучше сменить её на nested sets. Там тоже не сахар, но хоть как-то можно будет сделать. | |
|
|
|
|
|
|
|
для: Trianon
(21.07.2007 в 15:51)
| | Не знаю что-такое adjacency lists и nested sets, но спасибо, буду делать средствами PHP.
И попутно подвопрос: В моем случае у одной записи не может быть одинаковой ID и ParentID, как можно это контролировать? делать запросы типа DELETE WHERE ID = ParentID или можно сделать процедуру? подскажите, я не совсем знаком с хранимыми процедурами. | |
|
|
|
|
|
|
|
для: Wyfinger
(22.07.2007 в 03:43)
| | Не знаю что-такое adjacency lists
Это методика хранения деревьев в виде, который Вы описали так:
>ID | Parent ID | Name
> + | INT | CHAR
>и nested sets,
Это другая методика хранения деревьев.
В каждом узле хранятся id, left_bnd, right_bnd, level, так что
для любых узлов A, B находящихся в прямом порядке обхода в глубину, выполнено
для любых узлов A, B находящихся в прямом порядке обхода из глубины, выполнено
A.right_bnd < B.right_bnd
|
для любых узлов A, B таких что B является непосредственным потомком A, выполнено
A.left_bnd < B.left_bnd
A.right_bnd > B.right_bnd
B.level = A.level + 1
|
для корня R выполнено
R.left_bnd = 1
R.right_bnd = 2*ОбщееЧислоУзлов
R.level = 0;
|
и номера от 1 до 2*ОбщееЧислоУзлов без пропусков пробегают все маркерные поля left_bnd и right_bnd, перенумеровывая узлы в порядке обхода в глубину/из глубины. | |
|
|
|
|
|
|
|
для: Wyfinger
(22.07.2007 в 03:43)
| | >И попутно подвопрос: В моем случае у одной записи не может быть одинаковой ID и ParentID, как можно это контролировать? делать запросы типа DELETE WHERE ID = ParentID или можно сделать процедуру? подскажите, я не совсем знаком с хранимыми процедурами.
Вообще, для этого применяют триггеры.
Если Вы опишете parent_id как NOT NULL, а id как autoincrement, то как Вы сможете затолкать узел своим собственным потомком?
Или Вас волнует операция UPDATE? | |
|
|
|