新聞中心
隨著互聯(lián)網(wǎng)的快速發(fā)展,越來(lái)越多的業(yè)務(wù)系統(tǒng)需要實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)的數(shù)據(jù)存儲(chǔ)與管理。在實(shí)際應(yīng)用中,我們通常采用數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)的存儲(chǔ)與管理。那么如何使用數(shù)據(jù)庫(kù)實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)呢?本文將從以下幾個(gè)方面進(jìn)行介紹:

專業(yè)成都網(wǎng)站建設(shè)公司,做排名好的好網(wǎng)站,排在同行前面,為您帶來(lái)客戶和效益!創(chuàng)新互聯(lián)公司為您提供成都網(wǎng)站建設(shè),五站合一網(wǎng)站設(shè)計(jì)制作,服務(wù)好的網(wǎng)站設(shè)計(jì)公司,網(wǎng)站設(shè)計(jì)、網(wǎng)站制作負(fù)責(zé)任的成都網(wǎng)站制作公司!
1. 樹(shù)形結(jié)構(gòu)的定義
樹(shù)型結(jié)構(gòu)也稱為層次結(jié)構(gòu),是一種遞歸性的結(jié)構(gòu),它由節(jié)點(diǎn)構(gòu)成,節(jié)點(diǎn)與節(jié)點(diǎn)之間有著一定的從屬關(guān)系。樹(shù)形結(jié)構(gòu)通常具有一個(gè)根節(jié)點(diǎn)和若干個(gè)子節(jié)點(diǎn),每個(gè)子節(jié)點(diǎn)都可以有它自己的子節(jié)點(diǎn),形成了一顆樹(shù)狀圖的結(jié)構(gòu)。
在實(shí)際應(yīng)用中,常常使用樹(shù)型結(jié)構(gòu)來(lái)表示組織架構(gòu)、目錄結(jié)構(gòu)、分類標(biāo)簽等等。
2. 樹(shù)形結(jié)構(gòu)的實(shí)現(xiàn)方式
實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)有多種方式,比如多維數(shù)組、鏈表、遞歸、遍歷等。在數(shù)據(jù)庫(kù)中,通常采用兩種方式來(lái)實(shí)現(xiàn)樹(shù)形結(jié)構(gòu),分別是嵌套法和閉包表法。
嵌套法(Nested Set Model),也稱作嵌套模型、嵌套表示法,是一種用于存儲(chǔ)樹(shù)形結(jié)構(gòu)數(shù)據(jù)的模型。在嵌套模型中,每個(gè)節(jié)點(diǎn)都有左右兩個(gè)指針,通過(guò)這兩個(gè)指針來(lái)確定一個(gè)節(jié)點(diǎn)的所有子節(jié)點(diǎn)和父節(jié)點(diǎn)。
嵌套法的實(shí)現(xiàn)比較復(fù)雜,但是可以實(shí)現(xiàn)高效的讀取和遍歷。
閉包表法(Closure Table),也稱閉包表模型,是一種用于存儲(chǔ)樹(shù)形結(jié)構(gòu)數(shù)據(jù)的模型。在閉包表模型中,數(shù)據(jù)存儲(chǔ)在兩張表中,一張是節(jié)點(diǎn)表,另一張是關(guān)系表。節(jié)點(diǎn)表存儲(chǔ)了每個(gè)節(jié)點(diǎn)的信息,關(guān)系表用于存儲(chǔ)節(jié)點(diǎn)之間的從屬關(guān)系。
閉包表法的實(shí)現(xiàn)比較簡(jiǎn)單,但是讀取和遍歷相對(duì)較慢,適合規(guī)模較小的數(shù)據(jù)量。
3. 嵌套法的實(shí)現(xiàn)方式
在嵌套法中,每個(gè)節(jié)點(diǎn)都有左右兩個(gè)指針,用來(lái)表示左右子樹(shù)的范圍。左指針表示這個(gè)節(jié)點(diǎn)在整個(gè)樹(shù)中的左邊位置,右指針表示這個(gè)節(jié)點(diǎn)在整個(gè)樹(shù)中的右邊位置。根節(jié)點(diǎn)的左指針和右指針?lè)謩e為1和2n,其中n表示整個(gè)樹(shù)的節(jié)點(diǎn)數(shù)。
在實(shí)際應(yīng)用中,我們使用前序遍歷的方式來(lái)構(gòu)造樹(shù)狀結(jié)構(gòu)的左右指針。具體實(shí)現(xiàn)過(guò)程如下:
(1)定義一個(gè)節(jié)點(diǎn)表,包含節(jié)點(diǎn)ID、節(jié)點(diǎn)名稱、左邊界值、右邊界值等字段。
(2)遍歷整個(gè)樹(shù),采用遞歸的方式將方式將每個(gè)節(jié)點(diǎn)插入節(jié)點(diǎn)表中,并設(shè)置左右邊界值。
(3)插入完畢后,節(jié)點(diǎn)表中之一條數(shù)據(jù)的左邊界值就是1,右邊界值就是節(jié)點(diǎn)數(shù)的兩倍。通過(guò)左右邊界值可以快速地查詢某個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)和父節(jié)點(diǎn)。
(4)查詢節(jié)點(diǎn)時(shí),可以使用SQL的遞歸查詢語(yǔ)法來(lái)實(shí)現(xiàn)。比如使用WITH和UNION ALL關(guān)鍵字來(lái)實(shí)現(xiàn)節(jié)點(diǎn)的遞歸查詢。
(5)更新節(jié)點(diǎn)時(shí),需要重新計(jì)算左右邊界值,比較復(fù)雜。
4. 閉包表法的實(shí)現(xiàn)方式
在閉包表法中,數(shù)據(jù)存儲(chǔ)在兩張表中,一張是節(jié)點(diǎn)表,另一張是關(guān)系表。節(jié)點(diǎn)表存儲(chǔ)了每個(gè)節(jié)點(diǎn)的信息,關(guān)系表用于存儲(chǔ)節(jié)點(diǎn)之間的從屬關(guān)系。關(guān)系表中,每條記錄表示一個(gè)節(jié)點(diǎn)之間的從屬關(guān)系,包含子節(jié)點(diǎn)ID、父節(jié)點(diǎn)ID和深度三個(gè)字段。
在實(shí)際應(yīng)用中,我們使用以下方式來(lái)實(shí)現(xiàn)閉包表法:
(1)定義一個(gè)節(jié)點(diǎn)表,包含節(jié)點(diǎn)ID、節(jié)點(diǎn)名稱等字段。
(2)定義一個(gè)關(guān)系表,包含子節(jié)點(diǎn)ID、父節(jié)點(diǎn)ID、深度等字段。
(3)在插入節(jié)點(diǎn)時(shí),需要同時(shí)向節(jié)點(diǎn)表和關(guān)系表中插入記錄。向節(jié)點(diǎn)表中插入記錄,向關(guān)系表中插入以當(dāng)前節(jié)點(diǎn)ID和父節(jié)點(diǎn)ID為字段的記錄。同時(shí)需要遞歸插入父節(jié)點(diǎn)和其它祖先節(jié)點(diǎn)的關(guān)系。
(4)查詢節(jié)點(diǎn)時(shí),可以使用SQL的JOIN語(yǔ)法來(lái)實(shí)現(xiàn)。通過(guò)關(guān)系表可以快速地查詢某個(gè)節(jié)點(diǎn)的子節(jié)點(diǎn)和父節(jié)點(diǎn)。
(5)更新節(jié)點(diǎn)時(shí),需要重新計(jì)算節(jié)點(diǎn)和它的祖先節(jié)點(diǎn)的關(guān)系,比較復(fù)雜。
5.
在實(shí)際應(yīng)用中,我們可以根據(jù)實(shí)際需求來(lái)選擇合適的樹(shù)形結(jié)構(gòu)實(shí)現(xiàn)方式。嵌套法實(shí)現(xiàn)復(fù)雜,但是可以實(shí)現(xiàn)高效的讀取和遍歷;閉包表法實(shí)現(xiàn)簡(jiǎn)單,但是讀取和遍歷相對(duì)較慢,適合規(guī)模較小的數(shù)據(jù)量。因此,在選擇樹(shù)形結(jié)構(gòu)實(shí)現(xiàn)方式時(shí),需要結(jié)合實(shí)際需求進(jìn)行綜合評(píng)估。
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián)為您提供網(wǎng)站建設(shè)、網(wǎng)站制作、網(wǎng)頁(yè)設(shè)計(jì)及定制高端網(wǎng)站建設(shè)服務(wù)!
數(shù)據(jù)庫(kù)如何導(dǎo)出樹(shù)狀圖
:58·字?jǐn)?shù):37·閱讀:450
1、查詢?nèi)坎藛危p層循環(huán)方式)
/**
* 查詢?nèi)坎藛?/p>
*
* @return
*/
@Override
public List querAllTree() {
log.info(“查詢?nèi)繕?shù)”);
// 開(kāi)始時(shí)間
long stime = System.currentTimeMillis();
//查詢相對(duì)機(jī)構(gòu)
List OrgList = baseMapper.selectList(null);
// 轉(zhuǎn)換輸出格式
List resOrgList = OrgList.stream().map(u -> {
輸出對(duì)象 name = new 輸出對(duì)象();
BeanUtils.copyProperties(u, name);
return name;
}).collect(Collectors.toList());
//返回的樹(shù)形結(jié)構(gòu)數(shù)據(jù)
List trees = new ArrayList();
//循環(huán)菜單樹(shù)形數(shù)據(jù)
for (輸出對(duì)象menuTree : resOrgList) {
//菜單級(jí)別為0,則是一級(jí)數(shù)據(jù),根據(jù)實(shí)際情況判斷可修改相關(guān)關(guān)聯(lián)判斷
if (“00”.equals(menuTree.getOrgClass())) {
trees.add(menuTree);
for (輸出對(duì)象 it : resOrgList) {
//找出一級(jí)菜單下面的所有二級(jí)菜單,并加入到list中去
if (menuTree.getOrgCode().equals(it.getOrgSuperCode())) {
if (menuTree.getOrgChildrenMap() == null) {
menuTree.setOrgChildrenMap(new ArrayList());
}
menuTree.getOrgChildrenMap().add(it);
}
}
}
}
// 結(jié)束時(shí)間
long etime = System.currentTimeMillis();
log.info(“機(jī)構(gòu)數(shù)查詢耗時(shí):” + (etime – stime) + “毫秒”);
return trees;
}
2、查詢?nèi)坎藛危ㄟf歸方式)
/**
* 使用遞歸方法建樹(shù)
* @param menuTrees 子節(jié)點(diǎn)
* @return List
*/
public static List buildByRecursive(List menuTrees) {
List trees = new ArrayList();
for (輸出對(duì)象 menuTree : menuTrees) {
//菜單級(jí)別為00,則是一級(jí)數(shù)據(jù),根據(jù)實(shí)際情況判斷可修改相關(guān)關(guān)聯(lián)判斷
if (“00”.equals(menuTree.getOrgClass())) {
trees.add(findChildren(menuTree,menuTrees));
}
}
return trees;
}
/**
* 遞歸查找子節(jié)點(diǎn)
* @param menuTree 菜單數(shù)對(duì)象
* @param menuTrees 子節(jié)點(diǎn)
* @return MenuTree
*/
private static 輸出對(duì)象 findChildren(輸出對(duì)象 menuTree,List menuTrees) {
for (輸出對(duì)象 it : menuTrees) {
if(menuTree.getOrgCode().equals(it.getOrgSuperCode())) {
if (menuTree.getChildren() == null) {
menuTree.setChildren(new ArrayList());
}
menuTree.getOrgChildrenMap().add(findChildren(it,menuTrees));
}
}
return menuTree;
}
3、全部菜單樹(shù)(一次循環(huán))
/**
* 查詢?nèi)坎藛?/p>
*
* @return
*/
@Override
public List
querAllTree(TOrgInfoReq tOrgInfoReq) {
log.info(“查詢?nèi)繕?shù)”);
String orgPath = tOrgInfoReq.getOrgCode();
// 開(kāi)始時(shí)間
long stime = System.currentTimeMillis();
//查詢相對(duì)機(jī)構(gòu)
List
OrgList = tOrgInfoMapper.queryAllTree();
// 轉(zhuǎn)換輸出格式
List
如何用sql語(yǔ)句實(shí)現(xiàn)樹(shù)形的數(shù)據(jù)庫(kù)表查詢
如果樹(shù)的層數(shù)固定就可以雀蔽用語(yǔ)句查詢嘩橡,但效率比較低。例如你說(shuō)的三亂歲旁層:
select id,v2.name+name from t1 inner join
(select id,v1.name+name as name from t1 inner join
(select id,name from t1 where parentid = 0) v1 on t1.parentid = v1.id) v2 on t1.parentid = v2.id
數(shù)據(jù)庫(kù)實(shí)現(xiàn)樹(shù)形的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于數(shù)據(jù)庫(kù)實(shí)現(xiàn)樹(shù)形,如何使用數(shù)據(jù)庫(kù)實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)?,數(shù)據(jù)庫(kù)如何導(dǎo)出樹(shù)狀圖,如何用sql語(yǔ)句實(shí)現(xiàn)樹(shù)形的數(shù)據(jù)庫(kù)表查詢的信息別忘了在本站進(jìn)行查找喔。
創(chuàng)新互聯(lián)-老牌IDC、云計(jì)算及IT信息化服務(wù)領(lǐng)域的服務(wù)供應(yīng)商,業(yè)務(wù)涵蓋IDC(互聯(lián)網(wǎng)數(shù)據(jù)中心)服務(wù)、云計(jì)算服務(wù)、IT信息化、AI算力租賃平臺(tái)(智算云),軟件開(kāi)發(fā),網(wǎng)站建設(shè),咨詢熱線:028-86922220
本文名稱:如何使用數(shù)據(jù)庫(kù)實(shí)現(xiàn)樹(shù)形結(jié)構(gòu)?(數(shù)據(jù)庫(kù)實(shí)現(xiàn)樹(shù)形)
當(dāng)前URL:http://fisionsoft.com.cn/article/dpoiiec.html


咨詢
建站咨詢
