日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

树形结构在关系数据库中的设计

發(fā)布時間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树形结构在关系数据库中的设计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

在程序設(shè)計中,經(jīng)常以樹形結(jié)構(gòu)表示數(shù)據(jù)的層次關(guān)系,如菜單的結(jié)構(gòu)、商品的分類等。

這樣的層次結(jié)構(gòu)在關(guān)系數(shù)據(jù)庫中難以直觀地表示。常見的一種做法是用一個字段指向上級節(jié)點來表示記錄的上下級關(guān)系。

fidpidfname
? 1 ???Food
? 2? 1 ??Fruit
? 3? 2?Red
? 4? 3?Cherry
? 5? 2?Yellow
? 6? 5?Banana?
? 7? 1?Meat
? 8? 7?Beef
? 9? 7?Pork

當要查詢某一節(jié)點的上一級節(jié)點,比如 Beff,可以查詢 Beff(pid=7) 指向的那條記錄。

SELECT * FROM food WHERE fid = 7;

當要查詢某一節(jié)點的下一級節(jié)點,比如 Fruit,可以查詢 pid 指向 Fruit(fid=2) 的記錄。

SELECT * FROM food WHERE pid = 2;

?

另有一種基于左右值編碼的設(shè)計,這種設(shè)計方式的表結(jié)構(gòu)如下:

fidfnamelftrgt
? 1?Food? 1?? 18?
? 2?Fruit? 2? 11?
? 3?Red? 3?? 6?
? 4 ??Cherry?? 4? 5?
? 5?Yellow? 7? 10
? 6?Banana?? 8?? 9?
? 7?Meat? 12?? 17 ?
? 8?Beef? 13?? 14?
? 9?Pork? 15 ?? 16 ?

fid 跟節(jié)點的層次完全沒有關(guān)系,僅僅用來標識節(jié)點。引入了左右值來表示節(jié)點之間的關(guān)系,如下圖所示。

這樣的設(shè)計能夠方便地遍歷一棵樹,從左值數(shù)到右值便是先序遍歷了一棵(子)樹。更多詳細的設(shè)計,參見?http://www.sitepoint.com/hierarchical-data-database/?和?http://blog.csdn.net/monkey_d_meng/article/details/6647488

?

最后一種自己想到的設(shè)計:用字符串 str 來標識節(jié)點,并約定標識其上級節(jié)點的字符串為 substr(str, 1, length(str)-1)。例如,有一節(jié)點的以 "abc" 標識,則其上級節(jié)點以 "ab" 標識。

fidfname
?a?Food
?aa?Fruit
?aaa?Red
?aaaa??Cherry
?aab?Yellow
?aaba?Banana?
?ab?Meat
?aba?Beef
?abb?Pork

當要查詢某一節(jié)點的上一級節(jié)點,比如 Beff,因為 Beff?的 fid 為 "aba", 所以其上級節(jié)點的 fid 為 "ab"。

SELECT * FROM food WHERE fid = 'ab';

當要查詢某一節(jié)點的路徑,比如?Beff,因為 Beff?的 fid 為 "aba",所有其路徑為 a/ab/aba。

SELECT * FROM food WHERE fid IN ('a', 'ab', 'aba') ORDER BY fid;

當要查詢某一節(jié)點的下一級節(jié)點,比如 Fruit,因為?Fruit?的 fid 為 "aa",所以其下一級節(jié)點的 fid 是以 "aa" 開頭且比 "aa" 多一個字符的字符串。

SELECT * FROM food WHERE fid LIKE 'aa_';

當要查詢某一節(jié)點的所有下級節(jié)點,比如 Fruit,因為 Fruit?的 fid 為 "aa",所以其所有下級節(jié)點的 fid 是以 "aa" 開頭的字符串。

SELECT * FROM food WHERE fid LIKE 'aa%' AND fid != 'aa';

?

總結(jié)

第一種設(shè)計方式, 直觀方便,但是在對樹的遍歷過程中需要遞歸查詢,數(shù)據(jù)量大時,對效率的影響很大。這種設(shè)計適合的場景:1) 數(shù)據(jù)量不大的時候; 2) 只會經(jīng)常查詢節(jié)點的下一級節(jié)點而不會頻繁查詢節(jié)點的所有下級節(jié)點。

基于左右值編碼的設(shè)計方式,消除了遍歷樹時的遞歸操作,查詢效率高,但是設(shè)計較為復(fù)雜,增刪節(jié)點的代價較大。

第三種設(shè)計方式,同樣刪除了遍歷樹是的遞歸操作,無論是廣度優(yōu)先搜索(ORDER BY LENGTH(fid))還是深度優(yōu)先搜索(ORDER BY fid),都極為方便。這種設(shè)計在增刪節(jié)點時會影響著節(jié)點的所有下級節(jié)點的標識編碼。這種設(shè)計方式適合的場景:1) 樹形結(jié)構(gòu)基本穩(wěn)定,很少需要對其增刪節(jié)點; 2) 需要頻繁地查詢某個節(jié)點的所有下級節(jié)點。

轉(zhuǎn)載于:https://www.cnblogs.com/huey/p/4518979.html

總結(jié)

以上是生活随笔為你收集整理的树形结构在关系数据库中的设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。