Creating a list tree with SQLite

十年热恋 提交于 2020-08-01 06:40:10

问题


I'm trying to make a hierarchical list with PHP and an SQLite table setup like this:

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

The lists would be built with unordered lists and allow for this type of tree structure:

Item1
    |_Item3
    |_Item4
Item2
    |_Item5
        |_Item6

I've seen this done with directories and flat arrays, but I can't seem to make it work right with this structure and without a depth limit.


回答1:


You're using a textbook design for storing hierarchical data in an SQL database. This design is called Adjacency List, i.e. each node in the hierarchy has a parentid foreign key to its immediate parent.

With this design, you can't generate a tree like you describe and support arbitrary depth for the tree. You've already figured this out.

Most other SQL databases (PostgreSQL, Microsoft, Oracle, IBM DB2) support recursive queries, which solve this problem. But SQLite and MySQL don't support this feature of SQL yet.

So you need another solution to store the hierarchy. There are several solutions for this. See my presentation Models for Hierarchical Data with PHP and MySQL for descriptions and examples.

I usually prefer a design I call Closure Table, but each design has strength and weaknesses. Which one is best for your project depends on what kinds of queries you need to do efficiently with your data. So you should go study the solutions and choose one for yourself.




回答2:


I know this was asked log time ago, but with current SQLite version it is trivial to do and no need level depth as @Bill-Karwin says. So the correct answer should be reconsidered :)

My table has columns MCTMPLID and REF_TMPLID and my structure starting node is called 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');

And here is the main query, that builds tree structure

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

And here is result

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

I'm sure this can be modified to work tik OP's table structure, so let this sample be starting point Documentation and some samples https://www.sqlite.org/lang_with.html#rcex1



来源:https://stackoverflow.com/questions/3897952/creating-a-list-tree-with-sqlite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!