Создание списка дерева с помощью SQLite - PullRequest
8 голосов
/ 10 октября 2010

Я пытаюсь создать иерархический список с PHP и настройкой таблицы SQLite, например:

    |   itemid  |   parentid    |   name    |
    -----------------------------------------
    |   1       |   null        |   Item1   |
    |   2       |   null        |   Item2   |
    |   3       |   1           |   Item3   |
    |   4       |   1           |   Item4   |
    |   5       |   2           |   Item5   |
    |   6       |   5           |   Item6   |

Списки будут построены с неупорядоченными списками и допускают этот тип древовидной структуры:

Item1
    |_Item3
    |_Item4
Item2
    |_Item5
        |_Item6

Я видел, как это делается с каталогами и плоскими массивами, но я не могу заставить его работать правильно с этой структурой и без ограничения глубины.

Ответы [ 2 ]

13 голосов
/ 10 октября 2010

Вы используете дизайн учебника для хранения иерархических данных в базе данных SQL.Этот дизайн называется Список смежности , т. Е. Каждый узел в иерархии имеет parentid внешний ключ к своему непосредственному родителю.

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

Большинство других баз данных SQL (PostgreSQL, Microsoft, Oracle, IBM DB2) поддерживают рекурсивные запросы, которые решают эту проблему.Но SQLite и MySQL пока не поддерживают эту функцию SQL.

Так что вам нужно другое решение для хранения иерархии.Есть несколько решений для этого.Смотрите описание и примеры в моей презентации Модели для иерархических данных с PHP и MySQL .

Обычно я предпочитаю дизайн, который я называю Closure Table, но у каждого дизайна есть свои сильные и слабые стороны.Какой из них лучше всего подходит для вашего проекта, зависит от того, какие запросы вам нужно эффективно выполнять с вашими данными.Поэтому вам следует изучить решения и выбрать одно для себя.

0 голосов
/ 28 февраля 2019

Я знаю, что это было задано в журнале время назад, но с текущей версией SQLite это тривиально и не требует глубины уровня, как говорит @ Bill-Karwin Поэтому правильный ответ следует пересмотреть:)

В моей таблице есть столбцы MCTMPLID и REF_TMPLID, а начальный узел моей структуры называется ROOT

CREATE TABLE MyStruct (
  `TMPLID` text,
  `REF_TMPLID` text
);

INSERT INTO MyStruct
  (`TMPLID`, `REF_TMPLID`)
VALUES
  ('Root', NULL),
  ('Item1', "Root"),
  ('Item2', "Root"),
  ('Item3', 'Item1'),
  ('Item4', 'Item1'),
  ('Item5', 'Item2'),
  ('Item6', 'Item5');

А вот основной запрос, который строит древовидную структуру

WITH RECURSIVE
  under_root(name,level) AS (
    VALUES('Root',0)
    UNION ALL
    SELECT tmpl.TMPLID, under_root.level+1
      FROM MyStruct as tmpl JOIN under_root ON tmpl.REF_TMPLID=under_root.name
     ORDER BY 2 DESC
  )
SELECT substr('....................',1,level*3) || name as TreeStructure FROM under_root

А вот и результат

Root
...Item1
......Item3
......Item4
...Item2
......Item5
.........Item6

Я уверен, что это можно изменить, чтобы работать со структурой таблицы tik OP, так что пусть этот пример будет отправной точкой Документация и некоторые образцы https://www.sqlite.org/lang_with.html#rcex1

...