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. restfull api

    REST 表示状态传输.这是一个体系结构样式,可用于设计网络服务,可以被各种客户端消耗.核心思想是,不使用如CORBA,RPC或SOAP复杂的机制在机器之间进行连接,简单的 HTTP 用于使它们之间调 ...

  2. VBA_Excel_教程:分枝循环结构

    Sub 分枝() tmp = Cells(, ).Value '变量不用定义,当前写代码的Sheet Debug.Print tmp " Then Debug.Print "A&q ...

  3. MVC 為頁面的list資料重新命名

    function ReBookFileName() {                              $("#div_sortable").find("li[ ...

  4. 微信 网页授权获取用户基本信息(OAuth 2.0)

    // 相关设置 $APPID = ""; $AppSecret = ""; $html = ""; // 拼接 URL // 跳转该连接 获 ...

  5. Support Vector Machine (1) : 简单SVM原理

    目录 Support Vector Machine (1) : 简单SVM原理 Support Vector Machine (2) : Sequential Minimal Optimization ...

  6. DHCP服务器的开始方式

    方法一:采用DHCP服务器接口开启的方式 [Huawei]dhcp enable [Huawei]int g0/0/0[Huawei-GigabitEthernet0/0/0]ip add 192.1 ...

  7. free pascal 错误代码表

    free pascal 错误代码表 为了方便对照检查运行时错误代码,这里把所有的错误代码的含义整理出来.(最大序号为232,中间不一定连续.user.pdf P175) Run-time errors ...

  8. UVa 490 - Rotating Sentences

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=s ...

  9. 循序渐进Python3(七) -- 2-- 面向对象进阶

    面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象,根据模板创建的实例(即:对象),实 ...

  10. hibernate学习(设计一对多 关系 映射)

    1,配置文件: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-conf ...