MySQL多层级结构-区域表使用树详解

 更新时间:2016年07月08日 21:59:08   投稿:mdxy-dxy  
前面我们大概介绍了一下树结构表的基本使用。在我们项目中有好几块有用到多层级的概念。下面我们哪大家都比较熟悉的区域表来做演示

1.1. 前言

前面我们大概介绍了一下树结构表的基本使用。在我们项目中有好几块有用到多层级的概念。下面我们哪大家都比较熟悉的区域表来做演示。
1.2. 表结构和数据

区域表基本结构,可能在你的项目中还有包含其他字段。这边我只展示我们关心的字段:

CREATE TABLE `area` (
 `area_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '地区ID',
 `name` varchar(40) NOT NULL DEFAULT 'unkonw' COMMENT '地区名称',
 `area_code` varchar(10) NOT NULL DEFAULT 'unkonw' COMMENT '地区编码',
 `pid` int(11) DEFAULT NULL COMMENT '父id',
 `left_num` mediumint(8) unsigned NOT NULL COMMENT '节点左值',
 `right_num` mediumint(8) unsigned NOT NULL COMMENT '节点右值',
 PRIMARY KEY (`area_id`),
 KEY `idx$area$pid` (`pid`),
 KEY `idx$area$left_num` (`left_num`),
 KEY `idx$area$right_num` (`right_num`)
)

区域表数据: area
导入到test表

mysql -uroot -proot test < area.sql

1.1. 区域表的基本操作

查看 '广州' 的相关信息

SELECT * FROM area WHERE name LIKE '%广州%';
+---------+-----------+-----------+------+----------+-----------+
| area_id | name   | area_code | pid | left_num | right_num |
+---------+-----------+-----------+------+----------+-----------+
|  2148 | 广州市  | 440100  | 2147 |   2879 |   2904 |
+---------+-----------+-----------+------+----------+-----------+

查看 '广州' 所有孩子

SELECT c.* 
FROM area AS p, area AS c
WHERE c.left_num BETWEEN p.left_num AND p.right_num
 AND p.area_id = 2148;
+---------+-----------+-----------+------+----------+-----------+
| area_id | name   | area_code | pid | left_num | right_num |
+---------+-----------+-----------+------+----------+-----------+
|  2148 | 广州市  | 440100  | 2147 |   2879 |   2904 |
|  2161 | 从化市  | 440184  | 2148 |   2880 |   2881 |
|  2160 | 增城市  | 440183  | 2148 |   2882 |   2883 |
|  2159 | 花都区  | 440114  | 2148 |   2884 |   2885 |
|  2158 | 番禺区  | 440113  | 2148 |   2886 |   2887 |
|  2157 | 黄埔区  | 440112  | 2148 |   2888 |   2889 |
|  2156 | 白云区  | 440111  | 2148 |   2890 |   2891 |
|  2154 | 天河区  | 440106  | 2148 |   2892 |   2893 |
|  2153 | 海珠区  | 440105  | 2148 |   2894 |   2895 |
|  2152 | 越秀区  | 440104  | 2148 |   2896 |   2897 |
|  2151 | 荔湾区  | 440103  | 2148 |   2898 |   2899 |
|  2150 | 东山区  | 230406  | 2148 |   2900 |   2901 |
|  2149 | 其它区  | 440189  | 2148 |   2902 |   2903 |
+---------+-----------+-----------+------+----------+-----------+

查看 '广州' 所有孩子 和 深度 并显示层级关系

SELECT sub_child.area_id,
 (COUNT(sub_parent.name) - 1) AS depth,
 CONCAT(REPEAT(' ', (COUNT(sub_parent.name) - 1)), sub_child.name) AS name
FROM (
 SELECT child.* 
 FROM area AS parent, area AS child
 WHERE child.left_num BETWEEN parent.left_num AND parent.right_num
  AND parent.area_id = 2148
) AS sub_child, (  
 SELECT child.* 
 FROM area AS parent, area AS child
 WHERE child.left_num BETWEEN parent.left_num AND parent.right_num
  AND parent.area_id = 2148
) AS sub_parent
WHERE sub_child.left_num BETWEEN sub_parent.left_num AND sub_parent.right_num
GROUP BY sub_child.area_id
ORDER BY sub_child.left_num;
+---------+-------------+-------+
| area_id | name    | depth |
+---------+-------------+-------+
|  2148 | 广州市   |   0 |
|  2161 |  从化市  |   1 |
|  2160 |  增城市  |   1 |
|  2159 |  花都区  |   1 |
|  2158 |  番禺区  |   1 |
|  2157 |  黄埔区  |   1 |
|  2156 |  白云区  |   1 |
|  2154 |  天河区  |   1 |
|  2153 |  海珠区  |   1 |
|  2152 |  越秀区  |   1 |
|  2151 |  荔湾区  |   1 |
|  2150 |  东山区  |   1 |
|  2149 |  其它区  |   1 |
+---------+-------------+-------+

显示 '广州' 的直系祖先(包括自己)

SELECT p.* 
FROM area AS p, area AS c
WHERE c.left_num BETWEEN p.left_num AND p.right_num
 AND c.area_id = 2148;
+---------+-----------+-----------+------+----------+-----------+
| area_id | name   | area_code | pid | left_num | right_num |
+---------+-----------+-----------+------+----------+-----------+
|  2147 | 广东省  | 440000  |  0 |   2580 |   2905 |
|  2148 | 广州市  | 440100  | 2147 |   2879 |   2904 |
|  3611 | 中国   | 100000  |  -1 |    1 |   7218 |
+---------+-----------+-----------+------+----------+-----------+

向 '广州' 插入一个地区 '南沙区'

-- 更新左右值
UPDATE area SET left_num = left_num + 2 WHERE left_num > 2879;
UPDATE area SET right_num = right_num + 2 WHERE right_num > 2879;
 
-- 插入 '南沙区' 信息
INSERT INTO area
SELECT NULL, '南沙区', '440115', 2148, left_num + 1, left_num + 2
FROM area WHERE area_id = 2148;
 
-- 查看是否满足要求
SELECT c.* 
FROM area AS p, area AS c
WHERE c.left_num BETWEEN p.left_num AND p.right_num
 AND p.area_id = 2148;
+---------+-----------+-----------+------+----------+-----------+
| area_id | name   | area_code | pid | left_num | right_num |
+---------+-----------+-----------+------+----------+-----------+
|  2148 | 广州市  | 440100  | 2147 |   2879 |   2906 |
|  3612 | 南沙区  | 440115  | 2148 |   2880 |   2881 |
|  2161 | 从化市  | 440184  | 2148 |   2882 |   2883 |
|  2160 | 增城市  | 440183  | 2148 |   2884 |   2885 |
|  2159 | 花都区  | 440114  | 2148 |   2886 |   2887 |
|  2158 | 番禺区  | 440113  | 2148 |   2888 |   2889 |
|  2157 | 黄埔区  | 440112  | 2148 |   2890 |   2891 |
|  2156 | 白云区  | 440111  | 2148 |   2892 |   2893 |
|  2154 | 天河区  | 440106  | 2148 |   2894 |   2895 |
|  2153 | 海珠区  | 440105  | 2148 |   2896 |   2897 |
|  2152 | 越秀区  | 440104  | 2148 |   2898 |   2899 |
|  2151 | 荔湾区  | 440103  | 2148 |   2900 |   2901 |
|  2150 | 东山区  | 230406  | 2148 |   2902 |   2903 |
|  2149 | 其它区  | 440189  | 2148 |   2904 |   2905 |
+---------+-----------+-----------+------+----------+-----------+
您可能感兴趣的文章:

相关文章

  • MySQL 常用引擎总结分享

    MySQL 常用引擎总结分享

    这篇文章主要介绍了MySQL 常用引擎总结分享,MySQL有很多存储引擎,所谓的存储引擎是指用于存储、处理和保护数据的核心服务,更多常用引擎分享,需要的小伙伴可以参考下面文章内容
    2022-06-06
  • 手动管理MySQL8.0中的Undo表空间的使用

    手动管理MySQL8.0中的Undo表空间的使用

    本文主要介绍了MySQL 8.0中手动管理Undo表空间,包括创建、配置、使用和维护这些表空间的具体步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-07-07
  • Nacos配置MySQL8的方法

    Nacos配置MySQL8的方法

    这篇文章主要介绍了Nacos配置MySQL8的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • MySQL去除字段里数字的示例代码

    MySQL去除字段里数字的示例代码

    本文主要介绍了MySQL去除字段里数字的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • mysql中 redo日志详解

    mysql中 redo日志详解

    mysql都会把回滚时所需的东西记录下来,这些为了回滚而记录的东西称之为撤销日志,也就是我们今天要讲的undo日志,下面我们就来聊一聊这个undo日志,感兴趣的朋友跟随小编一起看看吧
    2024-06-06
  • Mysql中 unique列插入重复值该怎么解决呢

    Mysql中 unique列插入重复值该怎么解决呢

    本文给大家介绍mysql中unique列插入重复值的解决方案,主要基于mysql平台,通过这些,可以做到一些新的功能和应用。特此把本文本文分享给广大开发人员
    2015-11-11
  • mysql如何修改表结构(alter table),多列/多字段

    mysql如何修改表结构(alter table),多列/多字段

    这篇文章主要介绍了mysql如何修改表结构(alter table),多列/多字段问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • MySQL中一些优化straight_join技巧

    MySQL中一些优化straight_join技巧

    这篇文章主要介绍了MySQL中一些优化straight_join技巧,作者通过用户的实际案例分析,需要的朋友可以参考下
    2015-05-05
  • MySQL占用CPU过高排查过程及可能优化方案

    MySQL占用CPU过高排查过程及可能优化方案

    这篇文章主要介绍了MySQL占用CPU过高排查过程及可能优化方案,具有很好的参考价值,希望对大家的学习或工作有所帮助,感兴趣的朋友可以参考下
    2024-01-01
  • Mysql两种情况下更新字段中部分数据的方法

    Mysql两种情况下更新字段中部分数据的方法

    Mysql更新字段中部分数据的两种情况在下文给予详细的解决方法,感兴趣的朋友可以参考下哈
    2013-05-05

最新评论