五月综合激情婷婷六月,日韩欧美国产一区不卡,他扒开我内裤强吻我下面视频 ,无套内射无矿码免费看黄,天天躁,日日躁,狠狠躁

新聞動態(tài)

淺談MYSQL中樹形結(jié)構(gòu)表3種設(shè)計優(yōu)劣分析與分享

發(fā)布日期:2022-02-06 17:05 | 文章來源:站長之家

簡介

在開發(fā)中經(jīng)常遇到樹形結(jié)構(gòu)的場景,本文將以部門表為例對比幾種設(shè)計的優(yōu)缺點;

問題

需求背景:根據(jù)部門檢索人員,
問題:選擇一個頂級部門情況下,跨級展示當(dāng)前部門以及子部門下的所有人員,表怎么設(shè)計更合理 ?

遞歸嗎 ?遞歸可以解決,但是勢必消耗性能

設(shè)計1:鄰接表

注:(常見父Id設(shè)計)

表設(shè)計

CREATE TABLE `dept_info01` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `dept_id` int(10) NOT NULL COMMENT '部門id',
  `dept_name` varchar(100) NOT NULL COMMENT '部門名稱',
  `dept_parent_id` int(11) NOT NULL COMMENT '父部門id',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

這樣是最常見的設(shè)計,能正確的表達(dá)菜單的樹狀結(jié)構(gòu)且沒有冗余數(shù)據(jù),但在跨層級查詢需要遞歸處理。

SQL示例

1.查詢某一個節(jié)點的直接子集

SELECT * FROM dept_info01  WHERE dept_parent_id =1001

優(yōu)點

結(jié)構(gòu)簡單 ;

缺點

1.不使用遞歸情況下無法查詢某節(jié)點所有父級,所有子集

設(shè)計2:路徑枚舉

在設(shè)計1基礎(chǔ)上新增一個父部門id集字段,用來存儲所有父集,多個以固定分隔符分隔,比如逗號。

表設(shè)計

CREATE TABLE `dept_info02` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `dept_id` int(10) NOT NULL COMMENT '部門id',
  `dept_name` varchar(100) NOT NULL COMMENT '部門名稱',
  `dept_parent_id` int(11) NOT NULL COMMENT '父部門id',
  `dept_parent_ids` varchar(255) NOT NULL DEFAULT '' COMMENT '父部門id集',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

SQL示例

1.查詢所有子集
1).通過模糊查詢

SELECT
 *
FROM
	dept_info02
WHERE
	dept_parent_ids like '%1001%'

2).推薦使用 FIND_IN_SET 函數(shù)

SELECT
	* 
FROM
	dept_info02 
WHERE
	FIND_IN_SET( '1001', dept_parent_ids )

優(yōu)點

  • 方便查詢所有的子集 ;
  • 可以因此通過比較字符串dept_parent_ids長度獲取當(dāng)前節(jié)點層級 ;

缺點

  • 新增節(jié)點時需要將dept_parent_ids字段值處理好 ;
  • dept_parent_ids字段的長度很難確定,無論長度設(shè)為多大,都存在不能夠無限擴(kuò)展的情況 ;節(jié)
  • 點移動復(fù)雜,需要同時變更所有子集中的dept_parent_ids字段值 ;

設(shè)計3:閉包表

  • 閉包表是解決分級存儲的一個簡單而優(yōu)雅的解決方案,這是一種通過空間換取時間的方式 ;
  • 需要額外創(chuàng)建了一張TreePaths表它記錄了樹中所有節(jié)點間的關(guān)系 ;
  • 包含兩列,祖先列與后代列,即使這兩個節(jié)點之間不是直接的父子關(guān)系;同時增加一行指向節(jié)點自己 ;

表設(shè)計

主表

CREATE TABLE `dept_info03` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `dept_id` int(10) NOT NULL COMMENT '部門id',
  `dept_name` varchar(100) NOT NULL COMMENT '部門名稱',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

祖先后代關(guān)系表

CREATE TABLE `dept_tree_path_info` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `ancestor` int(10) NOT NULL COMMENT '祖先id',
  `descendant` int(10) NOT NULL COMMENT '后代id',
  `depth` tinyint(4) NOT NULL DEFAULT '0' COMMENT '層級深度',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

注:depth 層級深度字段 ,自我引用為 1,直接子節(jié)點為 2,再一下層為 3,一次類推,第幾層就是幾 。

SQL示例

插入新節(jié)點

INSERT INTO dept_tree_path_info (ancestor, descendant,depth)
SELECT t.ancestor, 3001,t.depth+1 FROM dept_tree_path_info AS t 
WHERE t.descendant = 2001
UNION ALL
SELECT 3001,3001,1

查詢所有祖先

SELECT
	c.*
FROM
	dept_info03 AS c
INNER JOIN dept_tree_path_info t ON c.dept_id = t.ancestor
WHERE
	t.descendant = 3001

查詢所有后代

SELECT
	c.*
FROM
	dept_info03 AS c
INNER JOIN dept_tree_path_info t ON c.dept_id = t.descendant
WHERE
t.ancestor = 1001

刪除所有子樹

DELETE 
FROM
	dept_tree_path_info 
WHERE
	descendant IN 
	( 
		SELECT
			a.dept_id 
		FROM
		( SELECT descendant dept_id FROM dept_tree_path_info WHERE  ancestor = 1001 ) a
	)

刪除葉子節(jié)點

DELETE 
FROM
	dept_tree_path_info 
WHERE
	descendant = 2001

移動節(jié)點

  • 刪除所有子樹(先斷開與原祖先的關(guān)系)
  • 建立新的關(guān)系

優(yōu)點

  • 非遞歸查詢減少冗余的計算時間 ;
  • 方便非遞歸查詢?nèi)我夤?jié)點所有的父集 ;
  • 方便查詢?nèi)我夤?jié)點所有的子集 ;
  • 可以實現(xiàn)無限層級 ;
  • 支持移動節(jié)點 ;

缺點

  • 層級太多情況下移動樹節(jié)點會帶來關(guān)系表多條操作 ;
  • 需要單獨一張表存儲對應(yīng)關(guān)系,在新增與編輯節(jié)點時操作相對復(fù)雜 ;

結(jié)合使用

可以將鄰接表方式與閉包表方式相結(jié)合使用。實際上就是將父id冗余到主表中,在一些只需要查詢直接關(guān)系的業(yè)務(wù)中就可以直接查詢主表,而不需要關(guān)聯(lián)2張表了。在需要跨級查詢時祖先后代關(guān)系表就顯得尤為重要。

表設(shè)計

主表

CREATE TABLE `dept_info04` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `dept_id` int(10) NOT NULL COMMENT '部門id',
  `dept_name` varchar(100) NOT NULL COMMENT '部門名稱',
  `dept_parent_id` int(11) NOT NULL COMMENT '父部門id',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

祖先后代關(guān)系表

CREATE TABLE `dept_tree_path_info` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',
  `ancestor` int(10) NOT NULL COMMENT '祖先id',
  `descendant` int(10) NOT NULL COMMENT '后代id',
  `depth` tinyint(4) NOT NULL DEFAULT '0' COMMENT '層級深度',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

總結(jié)

其實,在以往的工作中,曾見過不同類型的設(shè)計,鄰接表,路徑枚舉,鄰接表路徑枚舉一起來的都見過。每種設(shè)計都各有優(yōu)劣,如果選擇設(shè)計依賴于應(yīng)用程序中哪種操作最需要性能上的優(yōu)化。

設(shè)計 表數(shù)量 查詢直接子 查詢子樹 同時查詢多個節(jié)點子樹 插入 刪除 移動
鄰接表 1 簡單 需要遞歸 需要遞歸 簡單 簡單 簡單
枚舉路徑 1 簡單 簡單 查多次 相對復(fù)雜 簡單 復(fù)雜
閉包表 2 簡單 簡單 簡單 相對復(fù)雜 簡單 復(fù)雜

綜上所述

  • 只需要建立子父集關(guān)系中可以使用鄰接表方式 ;
  • 涉及向上查找,向下查找的需要建議使用閉包表方式 ;

到此這篇關(guān)于淺談MYSQL中樹形結(jié)構(gòu)表3種設(shè)計優(yōu)劣分析與分享的文章就介紹到這了,更多相關(guān)MYSQL 樹形結(jié)構(gòu)表內(nèi)容請搜索本站以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持本站!

香港穩(wěn)定服務(wù)器

版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。

實時開通

自選配置、實時開通

免備案

全球線路精選!

全天候客戶服務(wù)

7x24全年不間斷在線

專屬顧問服務(wù)

1對1客戶咨詢顧問

在線
客服

在線客服:7*24小時在線

客服
熱線

400-630-3752
7*24小時客服服務(wù)熱線

關(guān)注
微信

關(guān)注官方微信
頂部