HASH分区

HASH分区主要用来分散热点读,确保数据在预先确定个数的分区中尽可能平均分布。对一个表执行HASH分区时,MySQL会对分区键应用一个散列函数,以此确定数据应当放在N个分区中的哪个分区
MySQL支持两种HASH分区,常规HASH分区和线性HASH分区(LINEAR HASH);常规HASH使用的是取模算法,线性HASH分区使用的是一个线性的2的幂的运算法则

使用PARTITION BY HASH(expr)创建hash分区表,expr需要返回一个整数

下面的例子中创建了一个以store_id为分区键的hash分区表,如果你没有写partitions子句,那么默认为partitions 1

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

你也可以使用一个返回整型的表达是作为分区键

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH( YEAR(hired) )
PARTITIONS 4;

表达式expr必须返回一个非恒定的,非随机整数值(换句话说,应该是变化,但又是确定的)
同时应当注意的是,该表达式在每次insert update时都会被执行从而决定将数据放入哪个分区,所以如该表达式的性能低下,会影响整个分区表的性能
MySQL也不推荐使用涉及多列的hash表达式

常规HASH分区方式看上去挺不错的,通过取模的方式将数据尽可能的平均分布在每个分区中,让每个分区管理的数据都减少了,提高了查询的效率;课时当我们需要增加分区或者合并分区的时候,问题就出现了。假设原来是5个常规HASH分区,现在需要新增一个常规HASH分区,原来的取模算法是MOD(expr,5),根据余数0-4分布在五个分区中,现在新增一个分区,取模算法编程MOD(expr,6),根据余数0-5分布在6个分区中,原来5个分区中的数据大部分需要通过重新计算重新分区。
常规HASH分区在分区管理上带来的代价太大了,不适合需要灵活变动的需求。为了降低分区管理上的代价,MySQL提供了线性HASH分区,分区函数是一个线性的2的幂的运算法则

create table normal_hash(
    id int
)
partition by hash(id)
partitions 5; 

delimiter $$
create procedure normal_insert()
begin
	declare line int default 0;
	while line<1000
	do
		insert into normal_hash values(line);
		set line=line+1;
	end while;
end$$

call normal_insert();

mysql> select
    ->   partition_name part,
    ->   partition_expression expr,
    ->   partition_description descr,
    ->   table_rows
    -> from information_schema.partitions  where
    ->   table_schema = schema()
    ->   and table_name='normal_hash';
+------+------+-------+------------+
| part | expr | descr | table_rows |
+------+------+-------+------------+
| p0   | id   | NULL  |        200 |
| p1   | id   | NULL  |        200 |
| p2   | id   | NULL  |        200 |
| p3   | id   | NULL  |        200 |
| p4   | id   | NULL  |        200 |
+------+------+-------+------------+

线性hash分区

线性HASH分区和常规HASH分区在语法上的唯一区别是在”PARTITION BY”子句中添加LINEAR关键字

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LINEAR HASH( YEAR(hired) )
PARTITIONS 4;

使用线性HASH是,指定记录保存在哪个分区是可以计算出来的,假设将要保存的记录的分区编号设为N,num是一个非负整数,表示分割成分区的数量,那么N可以通过以下算法得到

首先,找到一个大于等于num的2的幂,这个值设为V,V可以通过下面的公式得到
V = POWER(2, CEILING(LOG(2, num)))
例如,刚才创建的employees表预先设定了4个分区,num=4
V = POWER(2, CEILING(LOG(2, 4)))
= POWER(2, CEILING(2))
= POWER(2, 2)
= 4

其次,设置N = F(column_list) & (v-1)
例如,我们刚才计算出V=4,现在计算stroe_id=234对于的值
N = F(column_list) & (v-1)
= 234 & (4-1)
= 2

当 N>=num
设置V=Ceiling(v/2),这时N=N & (V-1)
对于store_id=234这条记录,由于N=2<4;所以直接就能够判断这条记录会被存储在第二个分区中

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)

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

(6 >= 6 is TRUE: additional step required)

N = 6 & CEILING(8 / 2)
  = 6 & 3
  = 2

(2 >= 6 is FALSE: record stored in partition #2)

有意思的是,当线性HASH分区的个数是2的N次冥时,线性HASH分区的结果和常规HASH分区的结果是一致的

线性HASH分去的有点事,在分区维护(包括增加、删除、合并、拆分分区)时,MySQL能够处理的更加迅速;缺点是,对比常规HASH分区(取模)的时候,线性HASH各个分区之间数据的分布不太均衡

Mysql --分区表(6)Hash分区的更多相关文章

  1. Mysql --分区表(7)Key分区

    Key分区 按照Key进行分区非常类似于按照Hash进行分区,只不过Hash分区允许使用用户自定义的表达式,而Key分区不允许使用用户自定义的表达式,需要使用MySQL服务器提供的HASH函数;同时H ...

  2. mysql分区表之一:分区原理和优缺点【转】

    1.分区表的原理 分区表是由多个相关的底层表实现,这些底层表也是由句柄对象表示,所以我们也可以直接访问各个分区,存储引擎管理分区的各个底层表和管理普通表一样(所有的底层表都必须使用相同的存储引擎),分 ...

  3. MySQL 分区表,为什么分区键必须是主键的一部分?

    随着业务的不断发展,数据库中的数据会越来越多,相应地,单表的数据量也会越到越大,大到一个临界值,单表的查询性能就会下降. 这个临界值,并不能一概而论,它与硬件能力.具体业务有关. 虽然在很多 MySQ ...

  4. Mysql --分区表(5)Columns分区

    COLUMNS分区 COLUMNS分区是RANGE和LIST分区的变种.COLUMNS分区支持多列作为分区键进行分区 RANGE COLUNMS分区和LIST COLUMNS都支持非INT型列作为分区 ...

  5. MySQL分区表例子——List分区

    列表分区(List分区) 这里假设表中有一个sale_item_type 字段,数据类型为INT 型 当sale_item_type 为1,3,5的时候,作为一个分区 当sale_item_type  ...

  6. mysql分区表之二:MySQL的表的四种分区类型介绍

    一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了.如:某用户表的记录超过了600万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区 ...

  7. 高性能可扩展mysql 笔记(三)Hash分区、RANGE分区、LIST分区

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.MySQL分区表操作 1.定义:数据库表分区是数据库基本设计规范之一,分区表在物理上表现为多个文件, ...

  8. MySQL HASH分区

    200 ? "200px" : this.width)!important;} --> 介绍 基于给定的分区个数,将数据分配到不同的分区,HASH分区只能针对整数进行HASH ...

  9. [MySQL Reference Manual] 20 分区

    20 分区 20 分区 20.1 MySQL的分区概述 20.2 分区类型 20.2.1 RANGE分区 20.2.2 LIST分区 20.2.3 COLUMNS分区 20.2.3.1 RANGE C ...

随机推荐

  1. (整理)SQLServer 大数据的插入与查询

    最近几天一直在折腾大数据量的查询,最后在索引.分页存储过程和控件以及视图的帮助下,搞定了.这篇文章记录解决问题时候查看的网友的分享链接,以及大数据量数据的插入链接. DatagridView Virt ...

  2. java 学习备忘录(一):jsp项目建立及开发环境的基本配置

    Tomcat与eclipse配置 窗口->显示视图->Server 新建项目 建“动态web项目” 新建jsp文件 新建->其他->Web->jsp file 设置使用“ ...

  3. JS-改变页面的颜色(二)

    需求:点击页面的按钮,改变页面的颜色 思路:一先画出最简单的页面,二想办法获取页面的body节点,三想办法修改body节点的背景颜色属性,四通过一个方法获取随机的颜色值           和第一个例 ...

  4. Linux:远程到linux的图形界面

    一般linux都没有安装图形界面,可以通过VNC服务来实现步骤如下: 一.安装vnc server1.查看是否安装vncrpm -q vnc-serverpackage vnc is not inst ...

  5. 关于new/delete、malloc/free的内存泄漏检测

    情况一 new/delete 内存泄漏 1.在MFC中可以每一个cpp文件的头部添加以下一段宏来检测new申请而没用free释放的内存泄漏 #ifdef _DEBUG #define new DEBU ...

  6. VS2012调试时无法启动程序和拒绝访问问题汇总

    很多人在使用VS2012的时候会出现下面所示的问题,我也是,而且不止一次,也不是同样的问题,我这里就把一些常见的解决方法罗列一下.

  7. Linux命令之reset - 终端屏幕混乱的终结者

    用途说明 reset命令是用来重新初始化终端的(terminal initialization).在有些情况,终端显示会混乱无比,比如不小心显示了一个二进制文件,以前我在不知道reset命令时,只好将 ...

  8. Oracle 数据整理

    /* 大数据这块用到了 Oracle ... 记录一下. */ SELECT ssn,password FROM (Select ROWNUM AS ROWNO, T.* from ACCOUNT T ...

  9. 关于Eclipse项目中加入jquery.js文件报错(missing semicolon)问题

    在使用Eclipse3.7及以后的版本的时候,加入jQuery文件会报错(missing semicolon),文件中会显示红色小X,虽然这个错误并不会影响项目的运行,但是这个却会大大的影响到开发人员 ...

  10. redis cluster搭建

    一 .准备文件: Ruby :http://www.ruby-lang.org/en/downloads/    redis-3.0.5.tar.gz Redis:http://www.redis.c ...