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

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 |
+---------+-----------+-----------+------+----------+-----------+
(0)

相关推荐

  • MySQL多层级结构-树搜索介绍

    基本上在每个系统中都有那么几张表是自关联父子关系的结构.往往有很多人都是使用pid来做关联.在刚进入IT行业时使用CAKEPHP框架编写WEB的时候,使用它里面的一个ACL plugin实现权限管理的时候.发现一个表结构硬是不明白是怎么回事.具体表结构如下: CREATE TABLE acos ( id INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT, parent_id INTEGER(10) DEFAULT NULL, model VARCHAR(2

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

    1.1. 前言 前面我们大概介绍了一下树结构表的基本使用.在我们项目中有好几块有用到多层级的概念.下面我们哪大家都比较熟悉的区域表来做演示. 1.2. 表结构和数据 区域表基本结构,可能在你的项目中还有包含其他字段.这边我只展示我们关心的字段: CREATE TABLE `area` ( `area_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '地区ID', `name` varchar(40) NOT NULL DEFAULT 'unkonw' CO

  • mysql创建删除表的实例详解

    表的创建命令需要: 表的名称 字段名称 定义每个字段(类型.长度等) 语法 下面是通用的SQL语法用来创建MySQL表: CREATE TABLE table_name (column_name column_type); 现在,我们将在 test 数据库中创建以下表. create table tutorials_tbl( tutorial_id INT NOT NULL AUTO_INCREMENT, tutorial_title VARCHAR(100) NOT NULL, tuto

  • MySQL学习之数据库表五大约束详解小白篇

    目录 1.约束概念和分类 2.五大约束的添加和删除 2.1添加约束的六种方法 2.2三种删除约束的方式 2.3五大约束分别对应的添加删除方式(序号对应2.1和2.2) 2.4对于创建约束的总结 2.5对于主键和唯一的区别 3.自增长列 3.1概念 3.2在创建表的时候添加主键约束,并且完成主键自增长的例子 3.3自增长的添加和删除 3.4设置自增长步长 1.约束概念和分类 1.1约束的概念: 对表中的数据进行限定,保证数据的正确性,有效性,完整性 1.2约束分类 1.主键约束(primary k

  • MySQL数据库如何给表设置约束详解

    目录 一.PK(主键约束) 1.什么是主键? 2.怎么设置主键? 二.FK(外键约束) 1.什么是外键 2.怎么设置外键 三.unique(唯一约束) 1.什么是唯一约束? 2.如何设置唯一约束 四.notnull(非空) 五.default(默认值) 六.auto_increment(自增) 一.PK(主键约束) 1.什么是主键? 在了解主键之前,先了解一下什么是关键字 关键字:在表中具有唯一性的字段,比如一个人的身份证号,学号.一个表中可以有多个关键字. 主键也叫主关键字,就是由一个或多个关

  • MySQL的视图和索引用法与区别详解

    MySQL的视图 简单来说MySQL的视图就是对SELECT 命令的定义的一个快捷键,我们查询时会用到非常复杂的SELECT语句,而这个语句我们以后还会经常用到,我们可以经这个语句生产视图.视图是一个虚拟的表,它不存储数据,所用的数据都在真实的表中. 这样做的好处有: 1.防止有未经允许的租户访问到敏感数据 2.将多个物理表抽象成一个逻辑表 3.结果容易理解 4.获得数据更容易,很多人对SQL语句不太了解,我们可以通过创建视图的形式方便用户使用. 5.显示数据更容易. 6.维护程序更方便.调试视

  • MySQL使用表锁和行锁的场景详解

    目录 前言 全局锁 表级锁 表锁 元数据锁 意向锁 行级锁 总结 前言 MySQL Innodb 的锁可以说是执行引擎的并发基础了,有了锁才能保证数据的一致性.众所周知,我们都知道 Innodb 有全局锁.表级锁.行级锁三种,但你知道什么时候会用表锁,什么时候会用行锁吗? 虽然对 MySQL 的知识点挺熟悉的,但一开始看到这个问题,树哥也是有点懵,我还真没从这个角度去思考过.大家可以暂时 1 分钟思考下答案,后面我将带大家弄清楚这个问题. 对于这个问题,我只能粗略地想起一些片段,例如: 对于表级

  • python之sqlalchemy创建表的实例详解

    python之sqlalchemy创建表的实例详解 通过sqlalchemy创建表需要三要素:引擎,基类,元素 from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column,Integer,String 引擎:也就是实体数据库连接 engine = create_engine('mysql+pymysql://go

  • MySQL 普通索引和唯一索引的区别详解

    1 概念区分 普通索引和唯一索引 普通索引可重复,唯一索引和主键一样不能重复. 唯一索引可作为数据的一个合法验证手段,例如学生表的身份证号码字段,我们人为规定该字段不得重复,那么就使用唯一索引.(一般设置学号字段为主键) 主键和唯一索引 主键保证数据库里面的每一行都是唯一的,比如身份证,学号等,在表中要求唯一,不重复.唯一索引的作用跟主键的作用一样. 不同的是,在一张表里面只能有一个主键,主键不能为空,唯一索引可以有多个,唯一索引可以有一条记录为空,即保证跟别人不一样就行. 比如学生表,在学校里

  • MySQL分类排名和分组TOP N实例详解

    目录 表结构 题目一:获取每个科目下前五成绩排名(允许并列) 分析: 题目二:获取每个科目下最后两名学生的成绩平均值 分析: 题目三:获取每个科目下前五成绩排名(不允许并列) 分析: 总结 表结构 学生表如下: CREATE TABLE `t_student` ( `id` int NOT NULL AUTO_INCREMENT, `t_id` int DEFAULT NULL COMMENT '学科id', `score` int DEFAULT NULL COMMENT '分数', PRIM

  • Java实现跳跃表的示例详解

    跳表全称叫做跳跃表,简称跳表,是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表.跳表在原有的有序列表上面增加多级索引,通过索引来实现快速查找.跳表不仅能提高搜索性能,同时也提高插入和删除的性能,redis中的有序集合set就是用跳表实现的,面试时候也经常会问. 这里我们原始数据个数n=10,以间隔k=2建立索引,则第一层索引10/2=5个,第二层⌈10/2^2⌉=3个,第三层⌈10/2^3⌉=2个,第四层⌈10/2^4⌉=1个.根据上图我们来分析一下,跳表的结构是一棵树(除原始数据

随机推荐