使用SQLite创建列表树

时间:2010-10-09 21:33:29

标签: 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   |

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

Item1
    |_Item3
    |_Item4
Item2
    |_Item5
        |_Item6

我已经看到这样做了目录和平面数组,但我似乎无法使用这种结构并且没有深度限制。

2 个答案:

答案 0 :(得分:13)

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

使用此设计,您无法像描述的那样生成树并支持树的任意深度。你已经弄明白了。

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

因此,您需要另一种解决方案来存储层次结构。有几种解决方案。有关说明和示例,请参阅我的演示文稿Models for Hierarchical Data with PHP and MySQL

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

答案 1 :(得分:0)

我知道这是在日志记录之前询问的,但是对于当前的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