使用SQLite创建列表树

syl*_*bic 8 php sqlite hierarchical-data

我正在尝试使用PHP和SQLite表设置创建一个分层列表,如下所示:

    |   itemid  |   parentid    |   name    |
    -----------------------------------------
    |   1       |   null        |   Item1   |
    |   2       |   null        |   Item2   |
    |   3       |   1           |   Item3   |
    |   4       |   1           |   Item4   |
    |   5       |   2           |   Item5   |
    |   6       |   5           |   Item6   |
Run Code Online (Sandbox Code Playgroud)

这些列表将使用无序列表构建,并允许这种类型的树结构:

Item1
    |_Item3
    |_Item4
Item2
    |_Item5
        |_Item6
Run Code Online (Sandbox Code Playgroud)

我已经看到这对目录和平面数组完成了,但我似乎无法使其正常使用此结构并且没有深度限制.

Bil*_*win 13

您正在使用教科书设计将分层数据存储在SQL数据库中.此设计称为邻接列表,即层次结构中的每个节点都有一个parentid到其直接父节点的外键.

使用此设计,您无法生成类似于您描述的树并支持树的任意深度.你已经弄明白了.

大多数其他SQL数据库(PostgreSQL,Microsoft,Oracle,IBM DB2)都支持递归查询,从而解决了这个问题.但是SQLite和MySQL还不支持SQL的这个功能.

所以你需要另一个解决方案来存储层次结构.有几种解决方案.有关说明和示例,请参阅我的演示文稿使用PHP和MySQL的分层数据模型.

我通常更喜欢我称之为Closure Table的设计,但每种设计都有优点和缺点.哪一个最适合您的项目取决于您需要哪些类型的查询来有效地处理您的数据.所以你应该去研究解决方案并为自己选择一个.


Lix*_*xas 5

我知道这是在之前的日志中被问到的,但是对于当前的 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');
Run Code Online (Sandbox Code Playgroud)

这是构建树结构的主要查询

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
Run Code Online (Sandbox Code Playgroud)

这是结果

Root
...Item1
......Item3
......Item4
...Item2
......Item5
.........Item6
Run Code Online (Sandbox Code Playgroud)

我确定这可以修改为工作 tik OP 的表结构,所以让这个示例作为起点文档和一些示例https://www.sqlite.org/lang_with.html#rcex1