當前位置:吉日网官网 - 傳統節日 - 太棒了,設計並實現了壹個樹形數據表,避免外國人遞歸查詢所有子部門!

太棒了,設計並實現了壹個樹形數據表,避免外國人遞歸查詢所有子部門!

目錄

通常,樹形結構的存儲是將父節點的編號存儲在子節點上,以確定每個節點的父子關系。比如組織架構如下:[Image-a 14d 87-1651886833418]

對應表數據(部門):

[圖像上傳失敗...(圖片-a73b 71-1651886833418)]

部門表結構(部門)

這種方式很好,可以直觀的反映節點之間的關系,通常可以滿足大部分需求。但是,當業務需求變得很多,數據量巨大時,這種方法就不再適合生產了。

例如,PM增加了以下要求:

使用指定的部門號,逐層遞歸向下看,可能是大多數人會想到的方法。雖然mysql8.0中支持cte(公共表表達式),遞歸效率較傳統遞歸方式有明顯提高,但隨著部門樹層次深度的增加,查詢效率仍會變差。還有壹種方法是壹次性找出所有數據,放入內存進行處理(數據量小的時候可以選擇。數據量大,不怕挨打的人也可以選這個)~

遞歸查詢每壹層的數量,最後加起來。

方法1:您可以添加字段isLeaf來指示該節點是否是葉節點。方法二:直接查詢parent_id= current id的計數是否大於0。如果大於0,說明不是葉節點,如果等於0,說明是葉節點。在日常生活中,可能經常會用到上面提到的類似方法來解決類似的問題,但我認為這種方法在效率上並不是最優解。於是我開始尋找更好的方案來解決這些問題。

直到後來我查了壹個國外的博客,看到所謂的“改進的優先樹遍歷”的文章(天啊,是2003年發表的文章)~他具體是怎麽做的?或者回到之前的組織架構[Image-8b 11AC-165188683417]

我們先從根節點開始,將董事長的左值設為1,下級部門總經理的左值設為2,以此類推,開始沿邊遍歷,將左值加到每個節點上,遇到葉節點時將右值加到節點上,繼續沿邊遍歷,遍歷結束後返回到根節點的右側,就會得到壹個類似這樣的結構。[圖像上傳失敗...(圖片-f5f 389-165188683417)]

遍歷後,每個節點都有其對應的左右值。此時,您可以刪除parent_id字段,並添加LFT和RGT來存儲左右值。

[圖像上傳失敗...(圖片-278 DCA-165188683417)]

數據和結構都準備好了,我們來試著解決上面的需求吧~

根據當前表結構的規律可以發現,如果要找出所有的後代部門,只需要檢查左值在被搜索部門左右數之間的節點,並且都是他的子節點。比如在查詢首席執行官的所有子部門時,首席執行官的左右號碼分別是9和18,那麽lft字段的between查詢只需要9和18,查詢的結果就是被檢查部門和所有下級部門的數據;

& ltpre MP-original-font-size = " 17 " MP-original-line-height = " 27.200000762939453 " style = " margin:0px;填充:0px大綱:0px最大寬度:100%;框尺寸:邊框-框!重要;自動換行:斷字!重要;插入符號顏色:rgb(34,34,34);顏色:rgb(34,34,34);font-size:17px;字體樣式:正常;字體-變體-大寫:正常;字體粗細:400;字母間距:0.5440000295639038px孤兒:汽車;文本對齊:對齊;文本縮進:0px文本轉換:無;寡婦:汽車;字間距:0px-WebKit-text-size-adjust:auto;-WebKit-text-stroke-width:0px;文字-裝飾:無;行高:27.200000762939453像素& gt

完美~

& lt/pre & gt;

至此,或許可以說1的需求解決了,總數自然也就解決了。直接選擇count就可以了,真的沒有錯,但也不是必須的,因為有壹個簡單的公式可以直接計算出來。公式:合計=(右值-左值-1)/2例如:

有了用上述公式計算總數的經驗後,現在判斷是否是葉節點。有朋友已經知道怎麽做了,即如果右值為-1 ==左值,則是葉節點,或者如果左值為+1 ==右值,則是葉節點,否則不是。比如:設計部門,5-1 == 4,所以是葉節點。董事長,20-1!= 1,所以不是葉節點。至此,上述要求已經完美解決,接下來嘗試業務的基本操作。

添加部門時,需要在新節點位置的後續邊上加2,因為每個節點有兩個值。這個操作通常需要放到壹個事務中進行處理。例如,在R&D部門下增加壹個新部門:[圖片上傳失敗...(圖片-36a 719-1651886833417)]

對應的sql:

& ltpre MP-original-font-size = " 17 " MP-original-line-height = " 27.200000762939453 " style = " margin:0px;填充:0px大綱:0px最大寬度:100%;框尺寸:邊框-框!重要;自動換行:斷字!重要;插入符號顏色:rgb(34,34,34);顏色:rgb(34,34,34);font-size:17px;字體樣式:正常;字體-變體-大寫:正常;字體粗細:400;字母間距:0.5440000295639038px孤兒:汽車;文本對齊:對齊;文本縮進:0px文本轉換:無;寡婦:汽車;字間距:0px-WebKit-text-size-adjust:auto;-WebKit-text-stroke-width:0px;文字-裝飾:無;行高:27.200000762939453像素& gt

& lt/pre & gt;

刪除壹個部門類似於添加壹個部門,只是需要從被刪除節點的後續邊節點中減去2。比如刪除新增加的部門:[圖片上傳失敗...(圖片-504 FD 7-165188683417)]

對應的sql

& ltpre MP-original-font-size = " 17 " MP-original-line-height = " 27.200000762939453 " style = " margin:0px;填充:0px大綱:0px最大寬度:100%;框尺寸:邊框-框!重要;自動換行:斷字!重要;插入符號顏色:rgb(34,34,34);顏色:rgb(34,34,34);font-size:17px;字體樣式:正常;字體-變體-大寫:正常;字體粗細:400;字母間距:0.5440000295639038px孤兒:汽車;文本對齊:對齊;文本縮進:0px文本轉換:無;寡婦:汽車;字間距:0px-WebKit-text-size-adjust:auto;-WebKit-text-stroke-width:0px;文字-裝飾:無;行高:27.200000762939453像素& gt

& lt/pre & gt;

查詢壹個部門的直屬子部門(即不包括孫子部門),例如查詢總經理下的直屬子部門。回到產品部和行政總監【圖片上傳失敗很正常...(圖片-e2c 88 e-1651886833417)]。

對應的sql

& ltpre MP-original-font-size = " 17 " MP-original-line-height = " 27.200000762939453 " style = " margin:0px;填充:0px大綱:0px最大寬度:100%;框尺寸:邊框-框!重要;自動換行:斷字!重要;插入符號顏色:rgb(34,34,34);顏色:rgb(34,34,34);font-size:17px;字體樣式:正常;字體-變體-大寫:正常;字體粗細:400;字母間距:0.5440000295639038px孤兒:汽車;文本對齊:對齊;文本縮進:0px文本轉換:無;寡婦:汽車;字間距:0px-WebKit-text-size-adjust:auto;-WebKit-text-stroke-width:0px;文字-裝飾:無;行高:27.200000762939453像素& gt

& lt/pre & gt;

查詢某個部門的祖先鏈路徑。比如查詢產品部門的祖鏈路徑,正常情況下需要返回董事長總經理。

& ltpre MP-original-font-size = " 17 " MP-original-line-height = " 27.200000762939453 " style = " margin:0px;填充:0px大綱:0px最大寬度:100%;框尺寸:邊框-框!重要;自動換行:斷字!重要;插入符號顏色:rgb(34,34,34);顏色:rgb(34,34,34);font-size:17px;字體樣式:正常;字體-變體-大寫:正常;字體粗細:400;字母間距:0.5440000295639038px孤兒:汽車;文本對齊:對齊;文本縮進:0px文本轉換:無;寡婦:汽車;字間距:0px-WebKit-text-size-adjust:auto;-WebKit-text-stroke-width:0px;文字-裝飾:無;行高:27.200000762939453像素& gt

& lt/pre & gt;

就我個人而言,這種方法唯壹的缺點就是每次增刪,操作節點後續邊去的節點都要加/減2。

歡迎指正、交流和評論,共同探討更多解決方案。...

-鏈接指南:

/s/GDmrIwo89WVfDyAWYSBWQA

  • 上一篇:論中國古代儒學的演變特征
  • 下一篇:對於快破的爐石傳說,混亂牧師卡組分享
  • copyright 2024吉日网官网