Запрос структуры дерева SQLite - PullRequest
1 голос
/ 02 сентября 2011

У меня есть база данных таблиц, подобных этой:

tree{id,name,parent} content{id,content,parent}

Таблица tree содержит древовидную структуру, где, если parent равен 0, это верхний уровеньэлемент и, если он отличается, это идентификатор родителя из той же таблицы.

Таблица content имеет столбец parent, который является идентификатором из таблицы tree.

Я хочу получить всю цепочку элементов parent-children, когда им присваивается идентификатор для контента.

Я не думаю, что это лучшая структура для таблиц, и я думаю, что могу это изменить.

Что вы думаете по этому поводу, пожалуйста?

Ответы [ 2 ]

4 голосов
/ 02 сентября 2011

Прежде всего, я бы рекомендовал использовать parent = NULL вместо нуля для обозначения корневого узла, что позволило бы tree иметь внешний ключ на parent, который ссылается на id;ссылочная целостность полезна.

Затем вы можете включить материализованный путь от корневого узла к текущему узлу в каждой строке.Материализованный путь был бы строковым столбцом, который представляет путь от корневого узла до текущего узла;для ваших целей вы хотите использовать формат фиксированной ширины для каждого узла в пути, затем вы можете ASCIIbetical сортировать пути для извлечения записей в древовидном порядке (как в этом answer ).

Предположим, вы думали, что 99999 будет достаточно, чтобы покрыть все ваши узлы.Тогда у вас может быть строковый путь, подобный следующему:

'00001000110002300042'

Это будет представлять последовательность идентификаторов [1, 11, 23, 42], так что родительским узлом будет 42, прародителем 23 и так далее до корня 1.Чтобы получить всю ветку от узла к корню: возьмите путь, разделите его на части, чтобы получить идентификаторы, и извлеките все узлы одновременно, сортируя по материализованному пути, чтобы получить их в правильном порядке.

Этот подход также позволяет легко извлекать целые поддеревья сразу: просто создайте префикс пути, соответствующий желаемому поддереву, и выполните команду path LIKE 'pfx%' ORDER BY path, id, чтобы извлечь целое поддерево за один проход.Кроме того, большинство баз данных будет использовать индекс для выражения LIKE, который имеет корни в начале (т. Е. LIKE 'X%' для некоторых X), поэтому запросы такого типа могут выполняться довольно быстро.Вы также можете вычислить глубину узла с помощью простой длины строки и вычисления деления.

Вам нужно проделать небольшую дополнительную работу, чтобы построить материализованные пути, но не так много, и они выполняют много операций с деревом.красиво и просто, сохраняя при этом преимущества естественного представления дерева.

0 голосов
/ 08 декабря 2018

В качестве альтернативы вы можете использовать рекурсивное общее табличное выражение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...