在 MySQL 表中存儲(chǔ)樹(shù)形結(jié)構(gòu)數(shù)據(jù):
我們提供的服務(wù)有:成都網(wǎng)站建設(shè)、網(wǎng)站制作、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、漢陽(yáng)ssl等。為近1000家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的漢陽(yáng)網(wǎng)站制作公司
一般比較普遍的就是四種方法:(具體見(jiàn) SQL Anti-patterns這本書(shū))
Adjacency List:每一條記錄存parent_id
Path Enumerations:每一條記錄存整個(gè)tree path經(jīng)過(guò)的node枚舉
Nested Sets:每一條記錄存 nleft 和 nright
Closure Table:維護(hù)一個(gè)表,所有的tree path作為記錄進(jìn)行保存。
就是表需要有一個(gè)主鍵,比如 ID
然后還有一個(gè)字段,叫 父編號(hào), 比如 PID
再加上其他的字段,剩下的就是寫(xiě) SQL 的事情了。
例如下面這個(gè)表,就是一個(gè)可以做樹(shù)狀的。
CREATE TABLE test_tree (
test_id INT,
pid INT,
test_val VARCHAR(10),
PRIMARY KEY (test_id)
);
主要是要有ID,PID兩個(gè)字段,下面是我用的一個(gè)表,僅供參考:
CREATE TABLE [dbo].[Sys_Menu](
[ID] [int] NOT NULL,
[Code] [varchar](50) NOT NULL,
[PID] [int] NOT NULL,
[Name] [nvarchar](50) NULL,
[Url] [varchar](100) NULL,
[STATE] [bit] NOT NULL,
[IsSelected] [bit] NULL
) ON [PRIMARY]
GO
那個(gè)“熱心網(wǎng)友”回答是對(duì)的, 你這里的數(shù)據(jù)都是散放在幾個(gè)表里的, 不需要用start with connect by
直接一個(gè)表或者視圖, 列出son, father, grand_father, grand grand father即可。
唯一需要補(bǔ)充的就是, 需要用outter join, 因?yàn)間rand_father 不需要有son. 但是數(shù)據(jù)依然要列出。
select s.son_id, s.father_id, f.grand_father_id, g.grand_grand_faterh_id
from son s, father f, grand_father g
where s.father_id(+)=f.fatherid
and f.grand_father_id(+)=g.grand_father_id
f exists (select * from dbo.sysobjects where id = object_id(N'[tb]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [tb]
GO
--示例數(shù)據(jù)
create table [tb]([id] int identity(1,1),[pid] int,name varchar(20))
insert [tb] select 0,'中國(guó)'
union all select 0,'美國(guó)'
union all select 0,'加拿大'
union all select 1,'北京'
union all select 1,'上海'
union all select 1,'江蘇'
union all select 6,'蘇州'
union all select 7,'常熟'
union all select 6,'南京'
union all select 6,'無(wú)錫'
union all select 2,'紐約'
union all select 2,'舊金山'
go
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_id]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_id]
GO
/*--樹(shù)形數(shù)據(jù)處理
級(jí)別及排序字段
--鄒建 2003-12(引用請(qǐng)保留此信息)--*/
/*--調(diào)用示例
--調(diào)用函數(shù)實(shí)現(xiàn)分級(jí)顯示
select replicate('-',b.[level]*4)+a.name
from [tb] a,f_id()b
where a.[id]=b.[id]
order by b.sid
--*/
create function f_id()
returns @re table([id] int,[level] int,sid varchar(8000))
as
begin
declare @l int
set @l=0
insert @re select [id],@l,right(10000+[id],4)
from [tb] where [pid]=0
while @@rowcount0
begin
set @l=@l+1
insert @re select a.[id],@l,b.sid+right(10000+a.[id],4)
from [tb] a,@re b
where a.[pid]=b.[id] and b.[level]=@l-1
end
return
end
go
--調(diào)用函數(shù)實(shí)現(xiàn)分級(jí)顯示
select replicate('-',b.[level]*4)+a.name
from [tb] a,f_id()b
where a.[id]=b.[id]
order by b.sid
go
--刪除測(cè)試
drop table [tb]
drop function f_id
go
/*--結(jié)果
中國(guó)
----北京
----上海
----江蘇
--------蘇州
------------常熟
--------南京
--------無(wú)錫
美國(guó)
----紐約
----舊金山
加拿大
--*/
這個(gè)很好實(shí)現(xiàn)!就是添加和修改操作:
增加節(jié)點(diǎn):首先要獲取(在修改頁(yè)面)或指定(在sql語(yǔ)句中)parentid的值,然后插入數(shù)據(jù)就可以?。?/p>
修改節(jié)點(diǎn):可以根據(jù)menuid,修改節(jié)點(diǎn)的menuName或者parentid或者是同時(shí)修改它們倆。
有問(wèn)題請(qǐng)留言!