MySQL创建管理HASH分区


Posted in MySQL onApril 13, 2022

介绍

基于给定的分区个数,将数据分配到不同的分区,HASH分区只能针对整数进行HASH,对于非整形的字段只能通过表达式将其转换成整数。表达式可以是mysql中任意有效的函数或者表达式,对于非整形的HASH往表插入数据的过程中会多一步表达式的计算操作,所以不建议使用复杂的表达式这样会影响性能。

MYSQL支持两种HASH分区,常规HASH(HASH)和线性HASH(LINEAR HASH)。

一、常规HASH

常规hash是基于分区个数的取模(%)运算。根据余数插入到指定的分区

CREATE TABLE tbhash (
    id INT NOT NULL,
    store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4
;
ALTER TABLE tbhash ADD INDEX ix_store_id(store_id);
INSERT INTO tbhash() VALUES(1,100),(1,101),(2,102),(3,103),(4,104);

SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION 
FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tbhash';

MySQL创建管理HASH分区

其中100,104对4取模是0所以这两条数据被分配到了p0分区。

MySQL创建管理HASH分区

2.时间类型字段

CREATE TABLE employees (
    id INT NOT NULL,
    hired DATE NOT NULL DEFAULT '1970-01-01',
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

常规hash的分区非常的简便,通过取模的方式可以让数据非常平均的分布每一个分区,但是由于分区在创建表的时候已经固定了。如果新增或者收缩分区的数据迁移比较大。

二、线性HASH(LINEAR HASH)

LINEAR HASH和HASH的唯一区别就是PARTITION BY LINEAR HASH

CREATE TABLE tblinhash (
    id INT NOT NULL,
    hired DATE NOT NULL DEFAULT '1970-01-01'
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 6;

线性HASH的计算原理如下:

假设分区个数num=6,N表示数据最终存储的分区

sep1:V = POWER(2, CEILING(LOG(2, num))),LOG()是计算NUM以2为底的对数,CEILING()是向上取整,POWER()是取2的次方值;如果num的值是2的倍数那么这个表达式计算出来的结果不变。

V=POWER(2,CEILING(LOG(2,6)))

V=POWER(2,3)

V=8

sep2:N=values&(V-1);&位与运算,将两个值都转换成2进行求与运算,当都为1才为1;当num是2的倍数时由于V计算出来的结果不变,这时values&(V-1)=MOD(values/num)和时间HASH取模算出的结果是一致的,这时特殊情况只有当分区是2的倍数才是这种 情况。values是YEAR(hired)的值

sep3:while N>=num

sep3-1:N=N& (CEIL(V/ 2)- 1)

例如:

1.当插入的值是'2003-04-14'时

    V = POWER(2, CEILING( LOG(2,6) )) = 8

N = YEAR('2003-04-14') & (8 - 1)

= 2003 & 7

=3

(3 >= 6 is FALSE: record stored in partition #3),N不大于num所以存储在第3分区,注意这里的3指的是P3,分区号是从P0开始。

2.当插入的值是‘1998-10-19’

V = POWER(2, CEILING( LOG(2,6) )) = 8

N = YEAR('1998-10-19') & (8-1)

= 1998 & 7

= 6

(6 >= 6 is TRUE: additional step required),由于N>=num所以要进行第三步操作

N=N&(CEILING(8/2)-1)

=6&3

=2

(2>=6is FALSE:recored in partition #2),由于2不大于6所以存储在第2个分区,注意这里的3指的是P2,分区号是从P0开始。

INSERT INTO tblinhash() VALUES(1,'2003-04-14'),(2,'1998-10-19');
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION 
FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tblinhash';

MySQL创建管理HASH分区

EXPLAIN SELECT * FROM tblinhash WHERE hired='2003-04-14';

MySQL创建管理HASH分区

三、分区管理

常规HASH和线性HASH的增加收缩分区的原理是一样的。增加和收缩分区后原来的数据会根据现有的分区数量重新分布。HASH分区不能删除分区,所以不能使用DROP PARTITION操作进行分区删除操作;

只能通过ALTER TABLE ... COALESCE PARTITION num来合并分区,这里的num是减去的分区数量;

可以通过ALTER TABLE ... ADD PARTITION PARTITIONS num来增加分区,这里是null是在原先基础上再增加的分区数量。

1.合并分区

减去3个分区

ALTER TABLE tblinhash COALESCE PARTITION 3;
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION 
FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tblinhash';

MySQL创建管理HASH分区

注意:减去两个分区后,数据根据现有的分区进行了重新的分布,以'2003-04-14'为例:POWER(2, CEILING( LOG(2,3) ))=4,2003&(4-1)=3,3>=3,3&(CEILING(3/2)-1)=1,所以现在的'2003-04-14'这条记录由原来的p3变成了p1

MySQL创建管理HASH分区

2.增加分区

增加4个分区

ALTER TABLE tblinhash add PARTITION partitions 4;
SELECT PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION,TABLE_ROWS,SUBPARTITION_NAME,SUBPARTITION_METHOD,SUBPARTITION_EXPRESSION 
FROM information_schema.PARTITIONS WHERE TABLE_SCHEMA=SCHEMA() AND TABLE_NAME='tblinhash';

MySQL创建管理HASH分区

MySQL创建管理HASH分区

当在3个分区的基础上增加4个分区后,‘2003-04-14’由原来的p1变成了p3,而另一条记录由原来的p2变成了p6

四、移除表的分区

ALTER TABLE tablename
REMOVE PARTITIONING ;

注意:使用remove移除分区是仅仅移除分区的定义,并不会删除数据和drop PARTITION不一样,后者会连同数据一起删除

总结

常规HASH的数据分布更加均匀一些,也便于理解;目前还没有彻底理解为什么线性HASH在收缩和增加分区时处理的速度会更快,同时线性HASH的数据分布不均匀。

到此这篇关于MySQL分区之HASH分区的文章就介绍到这了!

MySQL 相关文章推荐
MySQL时间盲注的五种延时方法实现
May 18 MySQL
安装配置mysql及Navicat prenium的详细流程
Jun 10 MySQL
浅谈MySQL 亿级数据分页的优化
Jun 15 MySQL
浅谈MySQL之浅入深出页原理
Jun 23 MySQL
使用ORM新增数据在Mysql中的操作步骤
Jul 26 MySQL
深入解析MySQL索引数据结构
Oct 16 MySQL
SQL 聚合、分组和排序
Nov 11 MySQL
MySQL之MyISAM存储引擎的非聚簇索引详解
Mar 03 MySQL
面试提问mysql一张表到底能存多少数据
Mar 13 MySQL
MySQL中优化SQL语句的方法(show status、explain分析服务器状态信息)
Apr 09 MySQL
MySQL数据库优化之通过索引解决SQL性能问题
Apr 10 MySQL
深入理解MySQL中MVCC与BufferPool缓存机制
May 25 MySQL
MySQL创建管理RANGE分区
Apr 13 #MySQL
MySQL创建管理LIST分区
Apr 13 #MySQL
MySql分区类型及创建分区的方法
Apr 13 #MySQL
深入理解mysql事务隔离级别和存储引擎
mysql使用 not int 子查询隐含陷阱
Apr 12 #MySQL
MySQL数据库如何使用Shell进行连接
CentOS 7安装mysql5.7使用XtraBackUp备份工具命令详解
Apr 12 #MySQL
You might like
php判断字符串在另一个字符串位置的方法
2014/02/27 PHP
学习php设计模式 php实现状态模式
2015/12/07 PHP
纯PHP代码实现支付宝批量付款
2015/12/24 PHP
PHP 布尔值的自增与自减的实现方法
2018/05/03 PHP
php提高脚本性能的4个技巧
2020/08/18 PHP
javascript 隔行换色函数代码
2010/10/24 Javascript
jquery对表单操作2
2011/04/06 Javascript
根据经纬度计算地球上两点之间的距离js实现代码
2013/03/05 Javascript
封装html的select标签的js操作实例
2013/07/02 Javascript
jQuery快速上手:写jQuery与直接写JS的区别详细解析
2013/08/26 Javascript
js模拟点击以提交表单为例兼容主流浏览器
2013/11/29 Javascript
利用JS判断用户是否上网(连接网络)
2013/12/23 Javascript
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
jQuery仅用3行代码实现的显示与隐藏功能完整实例
2015/10/08 Javascript
Javascript 制作图形验证码实例详解
2016/12/22 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
javascript 封装Date日期类实例详解
2017/05/28 Javascript
JavaScript控制浏览器全屏显示简单示例
2018/07/05 Javascript
vue实现分页栏效果
2019/06/28 Javascript
react PropTypes校验传递的值操作示例
2020/04/28 Javascript
python解析xml文件实例分享
2013/12/04 Python
跟老齐学Python之复习if语句
2014/10/02 Python
Python实现基本数据结构中栈的操作示例
2017/12/04 Python
python3.x实现发送邮件功能
2018/05/22 Python
使用pytorch进行图像的顺序读取方法
2018/07/27 Python
Python基于SMTP协议实现发送邮件功能详解
2018/08/14 Python
python 使用turtule绘制递归图形(螺旋、二叉树、谢尔宾斯基三角形)
2019/05/30 Python
pytorch在fintune时将sequential中的层输出方法,以vgg为例
2019/08/20 Python
Python使用微信接入图灵机器人过程解析
2019/11/04 Python
Python实现将元组中的元素作为参数传入函数的操作
2020/06/05 Python
世界知名接发和假发品牌:Poze Hair
2017/03/08 全球购物
思想品德自我鉴定
2013/10/12 职场文书
社团招新策划书
2014/02/04 职场文书
工厂清洁工岗位职责
2015/02/14 职场文书
入党团支部推荐意见
2015/06/02 职场文书
AndroidStudio图片压缩工具ImgCompressPlugin使用实例
2022/08/05 Java/Android