ホームページ データベース mysql チュートリアル Mysql树型结构2种方式及相互转换_MySQL

Mysql树型结构2种方式及相互转换_MySQL

Jun 01, 2016 pm 12:59 PM
方法 構造

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

处理结束;

此算法已在项目中应用,代码是有版权的,就不贴了。

 

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

ラムダ式の構文と構造の特徴は何ですか? ラムダ式の構文と構造の特徴は何ですか? Apr 25, 2024 pm 01:12 PM

ラムダ式は名前のない匿名関数であり、その構文は (parameter_list)->expression です。匿名性、多様性、カリー化、閉鎖性が特徴です。実際のアプリケーションでは、ラムダ式を使用して、合計関数 sum_lambda=lambdax,y:x+y などの関数を簡潔に定義し、map() 関数をリストに適用して合計演算を実行できます。

インターネットの基本構造と技術の起源は何ですか? インターネットの基本構造と技術の起源は何ですか? Dec 15, 2020 pm 04:48 PM

インターネットの基本構造と技術はARPANETから生まれました。 ARPANETはコンピュータネットワーク技術発展のマイルストーンであり、その研究成果はネットワーク技術の発展を促進する上で重要な役割を果たし、インターネット形成の基礎を築きました。 Arpanet (Arpanet) は、米国国防高等研究計画局によって開発された世界初の実用的なパケット交換ネットワークであり、グローバル インターネットの祖先です。

MySQL.proc テーブルの構造と目的の詳細な分析 MySQL.proc テーブルの構造と目的の詳細な分析 Mar 15, 2024 pm 02:36 PM

MySQL.proc テーブルは、MySQL データベースにストアド プロシージャと関数の情報を格納するシステム テーブルです。その構造と目的を深く理解することで、MySQL のストアド プロシージャと関数の動作メカニズムをより深く理解し、関連する実行を行うことができます。管理と最適化。 MySQL.proc テーブルの構造と目的については以下で詳しく分析し、具体的なコード例を示します。 1. MySQL.proc テーブルの構造 MySQL.proc テーブルは、すべてのストアド プロシージャと関数の定義と関連情報を格納するシステム テーブルです。

Go言語での時間処理にはどのような方法があるのでしょうか? Go言語での時間処理にはどのような方法があるのでしょうか? Jun 10, 2023 pm 09:42 PM

最新のプログラミング言語として、Go 言語は開発において重要な役割を果たします。 Go 言語には、時間処理をより便利にするための組み込みの時間関数と構造がいくつか用意されています。この記事では、Go 言語でよく使われる時間処理メソッドをいくつか紹介します。 time.Now() time.Now() 関数を使用して現在時刻を取得できます: now:=time.Now()fmt.Println(now) 出力: 2019-06-131

HTML と CSS を使用して固定ナビゲーション メニューを含むレイアウトを実装する方法 HTML と CSS を使用して固定ナビゲーション メニューを含むレイアウトを実装する方法 Oct 26, 2023 am 11:02 AM

HTML と CSS を使用して固定ナビゲーション メニューを含むレイアウトを実装する方法 最新の Web デザインでは、固定ナビゲーション メニューは一般的なレイアウトの 1 つです。ナビゲーション メニューを常にページの上部または横に配置できるため、ユーザーは Web コンテンツを便利に閲覧できます。この記事では、HTML と CSS を使用して固定ナビゲーション メニューのレイアウトを実装する方法を紹介し、具体的なコード例を示します。まず、Web ページのコンテンツとナビゲーション メニューを表示する HTML 構造を作成する必要があります。これが簡単な例です

MySQL でモールの評価テーブル構造を設計するにはどうすればよいですか? MySQL でモールの評価テーブル構造を設計するにはどうすればよいですか? Oct 31, 2023 am 08:27 AM

MySQL でモールの評価テーブル構造を設計するにはどうすればよいですか?ショッピングモールのシステムにおいて、評価は最も重要な機能の一つです。評価は他のユーザーの参考になるだけでなく、販売者が製品に対するユーザーのフィードバックや意見を理解するのにも役立ちます。合理的な評価フォームの構造を設計することは、モールのシステムの運用とユーザーエクスペリエンスにとって非常に重要です。この記事では、MySQL でモールの評価テーブル構造を設計する方法と、具体的なコード例を紹介します。まず、product テーブルと user テーブルという 2 つの基本テーブルを作成する必要があります。商品一覧(商品

Chrome のアドレスバーから不要な URL を削除するにはどうすればよいですか? Chrome のアドレスバーから不要な URL を削除するにはどうすればよいですか? Mar 08, 2024 am 09:19 AM

Chrome は、アドレス バーに入力された URL を自動的に記録し、今後は自動的に「クエリの内容を関連付け」ます。しかし、多くの場合、一部の URL は必要ありません。それらを削除するにはどうすればよいでしょうか?編集者はこの問題によく遭遇し、以前に入力したアドレスがよく使用されるアドレスの前でブロックされ、目的の Web サイトにアクセスするために何度も選択する必要があります。削除する方法を少なくとも3回は探しました...毎回忘れてしまうので。 Chrome の公式ヘルプ Chrome キーボード ショートカットのアドレス バー ショートカットでは、削除ショートカット キーが明確になっています: ▍Windows はアドレス バーの関連付けのコンテンツを削除します。下矢印キーを押して対応するコンテンツを強調表示し、Shift+Delete キーを押します。 ▍macOSアドレスバーの関連付けコンテンツを削除します クリックダウン

Python の一般的なフロー制御構造は何ですか? Python の一般的なフロー制御構造は何ですか? Jan 20, 2024 am 10:38 AM

Python には、シーケンシャル構造、条件付き構造、ループ構造、ジャンプ構造という 4 つの一般的なフロー制御構造があります。以下では、それらを 1 つずつ紹介し、対応するコード例を示します。シーケンシャル構造: シーケンシャル構造は、特定のキーワードや構文を使用せずに、プログラムが上から下へ所定の順序で実行される構造です。サンプルコード: print("シーケンス構造例1はこちら")print("シーケンス構造例2はこちら")print("シーケンス構造例2はこちら")

See all articles