MySQL分区之HASH分区详解

目录
  • 介绍
  • 一、常规HASH
  • 二、线性HASH(LINEAR HASH)
  • 三、分区管理
    • 1.合并分区
    • 2.增加分区
  • 四、移除表的分区
  • 总结

介绍

基于给定的分区个数,将数据分配到不同的分区,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';

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

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';

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

三、分区管理

常规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';

注意:减去两个分区后,数据根据现有的分区进行了重新的分布,以'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

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';

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

四、移除表的分区

ALTER TABLE tablename
REMOVE PARTITIONING ;

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

分区系列文章:

RANGE分区:https://www.jb51.net/article/244269.htm

COLUMN分区:https://www.jb51.net/article/96515.htm

LIST分区:https://www.jb51.net/article/244256.htm

HASH分区:https://www.jb51.net/article/244277.htm

KEY分区:https://www.jb51.net/article/244282.htm

子分区:https://www.jb51.net/article/244294.htm

指定各分区路径:https://www.jb51.net/article/244296.htm

分区索引以及分区介绍总结:https://www.jb51.net/article/244300.htm

总结

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

到此这篇关于MySQL分区之HASH分区的文章就介绍到这了,更多相关MySQL HASH分区内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MySQL的表分区详解

    一.什么是表分区通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了.如:某用户表的记录超过了600万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区.当然也可根据其他的条件分区. 二.为什么要对表进行分区为了改善大型表以及具有各种访问模式的表的可伸缩性,可管理性和提高数据库效率.分区的一些优点包括:      1).与单个磁盘或文件系统分区相比,可以存储更多的数据.      2).对于那些已经失去保存意义的数据,通常可以通过删除与那些数据有关的

  • MySQL分区表的正确使用方法

    MySQL分区表概述 我们经常遇到一张表里面保存了上亿甚至过十亿的记录,这些表里面保存了大量的历史记录. 对于这些历史数据的清理是一个非常头疼事情,由于所有的数据都一个普通的表里.所以只能是启用一个或多个带where条件的delete语句去删除(一般where条件是时间). 这对数据库的造成了很大压力.即使我们把这些删除了,但底层的数据文件并没有变小.面对这类问题,最有效的方法就是在使用分区表.最常见的分区方法就是按照时间进行分区. 分区一个最大的优点就是可以非常高效的进行历史数据的清理. 1.

  • mysql的分区技术详细介绍

    一.概述 当 MySQL的总记录数超过了100万后,会出现性能的大幅度下降吗?答案是肯定的,但是,性能下降>的比率不一而同,要看系统的架构.应用程序.还有>包括索引.服务器硬件等多种因素而定.当有网友问我这个问题的时候,我最常见的回答>就是:分表,可以根据id区间或者时间先后顺序等多种规则来分表.分表很容易,然而由此所带来的应用程序甚至是架构方面的改动工作却不>容小觑,还包括将来的扩展性等. 在以前,一种解决方案就是使用 MERGE 类型,这是一个非常方便的做饭.架构和程序基本上不

  • 创建mysql表分区的方法

    表分区是最近才知道的哦 ,以前自己做都是分表来实现上亿级别的数据了,下面我来给大家介绍一下mysql表分区创建与使用吧,希望对各位同学会有所帮助.表分区的测试使用,主要内容来自于其他博客文章以及mysql5.1的参考手册mysql测试版本:mysql5.5.28mysql物理存储文件(有mysql配置的datadir决定存储路径)格式简介数据库engine为MYISAM frm表结构文件,myd表数据文件,myi表索引文件.INNODB engine对应的表物理存储文件innodb的数据库的物理

  • MySql数据分区操作之新增分区操作

    如果想在已经建好的表上进行分区,如果使用alter添加分区的话,mysql会提示错误: 复制代码 代码如下: ERROR 1505 <HY000> Partition management on a not partitioned table is not possible 正确的方法是新建一个具有分区的表,结构一致,然后用insert into 分区表 select * from 原始表; 测试创建分区表文件 复制代码 代码如下: CREATE TABLE tr (id INT, name

  • mysql使用教程之分区表的使用方法(删除分区表)

    MySQL使用分区表的好处: 1,可以把一些归类的数据放在一个分区中,可以减少服务器检查数据的数量加快查询.2,方便维护,通过删除分区来删除老的数据.3,分区数据可以被分布到不同的物理位置,可以做分布式有效利用多个硬盘驱动器. MySQL可以建立四种分区类型的分区: RANGE 分区:基于属于一个给定连续区间的列值,把多行分配给分区. LIST 分区:类似于按RANGE分区,区别在于LIST分区是基于列值匹配一个离散值集合中的某个值来进行选择.  www.jb51.net HASH分区:基于用户

  • MySQL分区之HASH分区详解

    目录 介绍 一.常规HASH 二.线性HASH(LINEAR HASH) 三.分区管理 1.合并分区 2.增加分区 四.移除表的分区 总结 介绍 基于给定的分区个数,将数据分配到不同的分区,HASH分区只能针对整数进行HASH,对于非整形的字段只能通过表达式将其转换成整数.表达式可以是mysql中任意有效的函数或者表达式,对于非整形的HASH往表插入数据的过程中会多一步表达式的计算操作,所以不建议使用复杂的表达式这样会影响性能. MYSQL支持两种HASH分区,常规HASH(HASH)和线性HA

  • InnoDB的关键特性-插入缓存,两次写,自适应hash索引详解

    InnoDB存储引擎的关键特性包括插入缓冲.两次写(double write).自适应哈希索引(adaptive hash index).这些特性为InnoDB存储引擎带来了更好的性能和更高的可靠性. 插入缓冲 插入缓冲是InnoDB存储引擎关键特性中最令人激动的.不过,这个名字可能会让人认为插入缓冲是缓冲池中的一个部分.其实不然,InnoDB缓冲池中有Insert Buffer信息固然不错,但是Insert Buffer和数据页一样,也是物理页的一个组成部分. 主键是行唯一的标识符,在应用程序

  • Mysql Online DDL的使用详解

    正文 Online DDL在MySQL 5.6才开始支持的,在5.5及之前版本,使用alter table/create index等命令进行表结构修改操作均会锁表,这在生产环境上明显是不可接受的. 在MySQL 5.7,Online DDL在性能和稳定性上不断得到优化,性能有显著优势,且对业务负载影响小,停写时间可控,相对pt-osc/gh-ost来说,无需安装第三方依赖包,同时支持Inplace算法的Online DDL,由于无需拷表,所需磁盘空间也更小. 先来看一个常见的DDL语句: AL

  • MySQL的Query Cache图文详解

    目录 一.原理概述 二.Query Cache系统变量 1. have_query_cache 2. query_cache_limit 3. query_cache_min_res_unit 4. query_cache_size 5. query_cache_type 6. query_cache_wlock_invalidate 三.Query Cache状态变量 1. Qcache_free_blocks 2. Qcache_free_memory 3. Qcache_hits 4. Q

  • mysql数据存储过程参数实例详解

    MySQL 存储过程参数有三种类型:in.out.inout.它们各有什么作用和特点呢? 一.MySQL 存储过程参数(in) MySQL 存储过程 "in" 参数:跟 C 语言的函数参数的值传递类似, MySQL 存储过程内部可能会修改此参数,但对 in 类型参数的修改,对调用者(caller)来说是不可见的(not visible). drop procedure if exists pr_param_in; create procedure pr_param_in ( in id

  • redhat7.1 安装mysql 5.7.10步骤详解(图文详解)

    在redhat下安装MySQL,步骤如下 Mysql目录安装位置:/usr/local/mysql 数据库保存位置:/data/mysql 日志保存位置:/data/log/mysql 下载安装包 http://downloads.mysql.com/archives/community/ 1. 获取mysql安装包,mysql-5.7.10-Linux-glibc2.5-x86_64.tar解压后目录如下. 2. 解压mysql-5.7.10-linux-glibc2.5-x86_64.tar

  • mysql 的replace into实例详解

    mysql 的replace into实例详解 replace into 跟 insert 功能类似,不同点在于:replace into 首先尝试插入数据到表中. 1.如果发现表中已经有此行数据(根据主键或者唯一索引判断)则先删除此行数据,然后插入新的数据. 2. 否则,直接插入新数据. 要注意的是:插入数据的表必须有主键或者是唯一索引!否则的话,replace into 会直接插入数据,这将导致表中出现重复的数据.  MySQL中replace into有三种写法: 代码如下: replac

  • PHP和MYSQL实现分页导航思路详解

    预期效果 思路 通过SQL语句 SELECT * FROM table LIMIT start end 来从MySql数据库 步骤 传入页码p: 根据页码获取数据php->mysql 显示数据+分页条 源码 github 链接 注意点 table,input,button等控件的样式不会继承body,需要重新定义如下 input,label, select,option,textarea,button,fieldset,legend,table{ font-size:18px; FONT-FAM

  • CentOS 6.6 源码编译安装MySQL 5.7.18教程详解

    一.添加用户和组 1.添加mysql用户组 # groupadd mysql 2.添加mysql用户 # useradd -g mysql -s /bin/nologin mysql -M 二.查看系统中是否安装mysql,如果安装需要卸载 # rpm -qa | grep mysql mysql-libs-5.1.73-3.el6_5.x86_64 # rpm -e mysql-libs-5.1.73-3.el6_5.x86_64 --nodeps 三.安装所需依赖包 # yum -y ins

  • MySQL对中文进行排序详解及实例

    MySQL对中文进行排序详解 MySQL默认只支持对日期.时间和英文字符串进行排序,如果对中文进行order by很可能得不到想要的结果,如下面的查询并不会按我们所想的根据汉字的拼音进行排序: SELECT * from user order by user_name; 如果相对中文进行排序的话,可以使用CONVERT(coloum_name USING GBK)将中文转为GBK编码形式,然后再排序,就可以实现根据汉子的拼音进行排序: SELECT * from user order by CO

随机推荐