用邻接模型在数据库中存储树形结构,根节点的pid为什么用null表示,不用0

用邻接模型在数据库中存储树形结构,根节点的pid为什么用null表示,不用0,第1张

方法一般有下面两种。

1:邻接列表模型 2:改进前序遍历树算法

1:邻接列表模型

意思是在数据库的表结构中,加一个parent的字段来表示,这个节点的父节点是哪条数据。

前两天看论坛中有个人的实现方式把这个改进了,感觉效率会更好,方案如下:

表字段:id(int自增)、name(String)、parentId(int)、depth(int)

id:int型自增索引,无任何实际意义。

name:业务字段。

parentId:父节点的自增索引。

depth:节点深度,子节点depth >父节点depth,除此之外该字段无任何限制。

加载方式:从数据库中按depth升序查询到所有数据,返回为LinkedHashMap<id, 对象>,然后遍历该Map的value集逐一加载到界面,遍历的时候根据parentId去Map中找父节点。

由于采用LinkedHashMap,所以存入的数据不会乱序,又有了depth的升序排列,可以保证加载子节点时其父节点一定已被加载,缓存的Map还可留作它用,这比List方便多了。

2:改进前序遍历树算法

数据库的表结构中增加两个字段: 左值,右值,来表示一个具体的节点。

树形结构统一使用下面的测试表与测试数据

CREATE TABLE test_tree (

test_id INT,

pid INT,

test_val VARCHAR(10),

PRIMARY KEY (test_id)

)

INSERT INTO test_tree VALUES(1, NULL, '.NET')

INSERT INTO test_tree VALUES(2, 1, 'C#')

INSERT INTO test_tree VALUES(3, 1, 'J#')

INSERT INTO test_tree VALUES(4, 1, 'ASP.NET')

INSERT INTO test_tree VALUES(5, 1, 'VB.NET')

INSERT INTO test_tree VALUES(6, NULL, 'J2EE')

INSERT INTO test_tree VALUES(7, 6, 'EJB')

INSERT INTO test_tree VALUES(8, 6, 'Servlet')

INSERT INTO test_tree VALUES(9, 6, 'JSP')

INSERT INTO test_tree VALUES(10, NULL, 'Database')

INSERT INTO test_tree VALUES(11, 10,'DB2')

INSERT INTO test_tree VALUES(12, 10,'MySQL')

INSERT INTO test_tree VALUES(13, 10,'Oracle')

INSERT INTO test_tree VALUES(14, 10,'SQL Server')

INSERT INTO test_tree VALUES(15, 13,'PL/SQL')

INSERT INTO test_tree VALUES(16, 15,'Function')

INSERT INTO test_tree VALUES(17, 15,'Procedure')

INSERT INTO test_tree VALUES(18, 15,'Package')

INSERT INTO test_tree VALUES(19, 15,'Cursor')

INSERT INTO test_tree VALUES(20, 14,'T-SQL')

Oracle

使用 START WITH CONNECT BY

语句实现树状查询

SQL>ed

Wrote file afiedt.buf

1 SELECT

2LPAD(' ', 2*(LEVEL-1)) || test_val AS test_val

3 FROM

4test_tree

5 START WITH

6test_id IN (1, 6, 10)

7* CONNECT BY PRIOR test_id = pid

SQL>/

TEST_VAL

-----------------------------------------------------------

.NET

C#

J#

ASP.NET

VB.NET

J2EE

EJB

Servlet

JSP

Database

DB2

TEST_VAL

-----------------------------------------------------------

MySQL

Oracle

PL/SQL

Function

Procedure

Package

Cursor

SQL Server

T-SQL

20 rows selected.

SQL Server

使用 Common Table Expression (CTE) 来实现 递归调用。

1>WITH StepCTE

2>AS

3>(

4>SELECT

5> test_id,

6> pid,

7> test_val,

8> 1 as Lev

9>FROM

10> test_tree

11>WHERE

12> test_id IN (1,6,10)

13>UNION ALL

14>SELECT

15> T.test_id,

16> T.pid,

17> T.test_val,

18> CTE.Lev + 1

19>FROM

20> test_tree T INNER JOIN StepCTE CTE

21> ON T.pid = CTE.test_id

22>)

23>SELECT

24> test_id, pid, test_val, Lev

25>FROM StepCTE

26>go

test_id pid test_val Lev

----------- ----------- ---------- -----------

1NULL .NET 1

6NULL J2EE 1

10NULL Database 1

11 10 DB2 2

12 10 MySQL2

13 10 Oracle 2

14 10 SQL Server 2

20 14 T-SQL3

15 13 PL/SQL 3

16 15 Function 4

17 15 Procedure4

18 15 Package 4

19 15 Cursor 4

7 6 EJB 2

8 6 Servlet 2

9 6 JSP 2

2 1 C# 2

3 1 J# 2

4 1 ASP.NET 2

5 1 VB.NET 2

(20 行受影响)

就是表需要有一个主键,比如 ID

然后还有一个字段,叫 父编号, 比如 PID

再加上其他的字段,剩下的就是写 SQL 的事情了。

例如下面这个表,就是一个可以做树状的。

CREATE TABLE test_tree (

test_id INT,

pid INT,

test_val VARCHAR(10),

PRIMARY KEY (test_id)

)


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/9892914.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-03
下一篇 2023-05-03

发表评论

登录后才能评论

评论列表(0条)

保存