Mysql树型结构2种方式及相互转换_MySQL
Mysql实现树型结构,数据库上常见有2种方式:领接表、预排序遍历树(MPTT)。
领接表方式——
主要依赖于一个 parent 字段,用于指向上级节点,将相邻的上下级节点连接起来,id 为自动递增自动,parent_id 为上级节点的 id。
领接表方式的优点在于容易理解,代码也比较简单明了。缺点则是递归中的 SQL 查询会导致负载变大,特别是需要处理比较大型的树状结构的时候,查询语句会随着层级的增加而增加,WEB 应用的瓶颈基本都在数据库方面,所以这是一个比较致命的缺点,直接导致树结构的扩展困难重重。
排序遍历树方式
现在我们来聊聊第二种方式─预排序遍历树方式(即通常所说的 MPTT,Modified Preorder Tree Traversal)。此算法是在第一种方式的基础之上,给每个节点增加一个左、右数字,用于标识节点的遍历顺序,如下图所示:
vcq9yrXA/Q==" title="PHP+Mysql树型结构(无限分类)数据库设计的2种方式实例" />
从根节点开始左边为 1,然后下一个节点的左边为 2,以此类推,到最低层节点之后,最低层节点的右边为其左边的数字加 1。顺着这些节点,我们可以很容易地遍历完整个树。根据上图,我们对数据表做一些改变,增加两个字段,lft 和 rgt 用于存储左右数字( left 和 right 是 MySQL 的保留字,所以改用简写)。
可以看出,由于MPTT方式存储不仅包含隶属关系,还包括了顺序,因此在读取子树时不需递归,效率大大提高。
下面面讨论下如何在这两着间转换.
MPTT转领接表比较容易,只要寻找层级比当前节点小1,且lft当前节点rgt的节点,即为父节点。
领接表转MPTT,一般直观想到的是递归生成。但是这个不是尾递归,递归层数有限制, mysql没有数组自建堆栈要用表,效率很低,怎么办?
笔者设计了一个近似递推的算法,分享一下:
首先确定问题:领接表结构(id,pid),目标MPTT表结构(id,lvl,lft,rgt)。
为处理需要,MPTT表增加cnt、seq字段,用于记录节点及其子节点的个数、在MPTT中遍历的序号。
处理过程算法如下:
1】根节点,转入MPTT表,令lvl=1,lft=1,rgt=null,cnt=null,seq=1;
2】逐层处理p的子节点,lvl+1;
3】从最底层(lvl最大)向上(lvl递减)处理各层的节点,cnt=子节点的cnt数+1
4】从最上曾(lvl=1)向下(lvl递增)处理各层的节点,seq=父节点seq+ sum(id小于本节点的兄弟节点的cnt)+1
5】对每一个节点,lft=seq*2-lvl,rgt = lft +cnt *2 -1
处理结束;
此算法已在项目中应用,代码是有版权的,就不贴了。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Lambda表達式是無名稱的匿名函數,其語法為:(parameter_list)->expression。它們具有匿名性、多樣性、柯里化和閉包等特徵。在實際應用中,Lambda表達式可用於簡潔地定義函數,如求和函數sum_lambda=lambdax,y:x+y,並透過map()函數應用於列表來進行求和操作。

internet的基本架構與技術起源於ARPANET。 ARPANET是電腦網路技術發展中的一個里程碑,它的研究成果對促進網路技術的發展起到了重要的作用,並未internet的形成奠定了基礎。 arpanet(阿帕網)為美國國防部高級研究計劃署開發的世界上第一個運營的數據包交換網絡,它是全球互聯網的始祖。

Go語言作為一個現代化的程式語言,時間在開發中佔有很重要的地位。 Go語言提供了一些內建的時間函數和結構體,使得時間的處理變得更加便捷。在本篇文章中,將會介紹一些Go語言常用的時間處理方式。 time.Now()我們可以使用time.Now()函數取得目前的時間:now:=time.Now()fmt.Println(now)輸出:2019-06-131

MySQL.proc表是MySQL資料庫中儲存預存程序和函數資訊的系統表,透過深入了解其結構及用途,可以更好地理解預存程序和函數在MySQL中的運作機制,並進行相關的管理和最佳化。以下將詳細解析MySQL.proc表的結構及用途,並提供具體的程式碼範例。 1.MySQL.proc表的結構MySQL.proc表是一個系統表,儲存了所有預存程序和函數的定義和相關信息

如何使用HTML和CSS實現一個具有固定導航選單的佈局在現代網頁設計中,固定導航選單是常見的佈局之一。它可以使導航選單始終保持在頁面頂部或側邊,使用戶可以輕鬆瀏覽網頁內容。本文將介紹如何使用HTML和CSS實作一個具有固定導航選單的佈局,並提供具體的程式碼範例。首先,需要建立一個HTML結構來呈現網頁的內容和導覽選單。以下是一個簡單的範例

如何在MySQL中設計商城的評估表結構?在一個商城系統中,評價是非常重要的功能之一。評價不僅可以提供給其他使用者參考,還可以幫助商家了解使用者對商品的回饋和意見。設計一個合理的評價表結構對於商城系統的運作和使用者體驗至關重要。本文將介紹如何在MySQL中設計商城的評估表結構,並提供具體的程式碼範例。首先,我們需要建立兩個基本的表:商品表和使用者表。商品表(produc

Chrome會自動在網址列中記錄曾經輸入過的網址,並且會在未來自動“聯想查詢內容”,但很多時候我們並不需要一些網址,如何刪掉它們呢?小編常常遇到這樣的困擾,曾經輸入過的地址,會擋在常用地址的前面,導致需要選好幾次才能進入需要的網站。為此我也找過至少3次如何刪除了,因為…每次都會忘記。在Chrome官方幫助Chrome鍵盤快捷鍵的地址列快捷鍵中,就明確了刪除快捷鍵:▍Windows刪除地址列聯想內容按向下箭頭鍵以突出顯示相應內容,然後按Shift+Delete鍵▍macOS刪除地址欄聯想內容按向下

Python中有四種常見的製程控制結構,分別是順序結構、條件結構、循環結構、跳轉結構。下面將一一介紹並提供對應的程式碼範例。順序結構:順序結構是程式從上到下依照預定的順序執行的結構,沒有特定的關鍵字或語法。範例程式碼:print("這是順序結構範例1")print("這是順序結構範例2")print("這是順
