位置: IT常识 - 正文

MySQL分区表详解(mysql分区分表原理)

编辑:rootadmin
MySQL分区表详解

推荐整理分享MySQL分区表详解(mysql分区分表原理),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:mysql分区分表原理,MySQL分区表详解,mysql的分区表,mysql5.7分区表,mysql5.7分区表,MySQL分区表详解,mysql的分区表,mysql的分区,内容如对您有帮助,希望把文章链接给更多的朋友!

通常情况下,同一张表的数据在物理层面都是存放在一起的。随着业务增长,当同一张表的数据量过大时,会带来管理上的不便。而分区特性可以将一张表从物理层面根据一定的规则将数据划分为多个分区,多个分区可以单独管理,甚至存放在不同的磁盘/文件系统上,提升效率。

分区表的优点:

数据可以跨磁盘/文件系统存储,适合存储大量数据。数据的管理非常方便,以分区为单位操作数据,不会影响其他分区的正常运行。数据查询上在某些条件可以利用分区裁剪(partition pruning)特性,将搜索范围快速定位到特性分区,提升查询性能。

对于应用来说,表依然是一个逻辑整体,但数据库可以针对不同的数据分区独立执行管理操作,不影响其他分区的运行。而数据划分的规则即称为分区函数,数据写入表时,会根据运算结果决定写入哪个分区。

MySQL的分区插件与存储引擎运行在不同的层,因此大部分存储引擎都可以利用MySQL的分区特性,只有少数存储引擎(merge,CSV,federated)不支持分区特性。若某张表使用的分区特性,则所有的分区都需要使用相同的存储引擎,且分区特性会同时应用到数据和索引上。

MySQL的分区类型:

一、分区的类型

1. Range partition(范围分区)

2. List partition(列表分区)

3. Hash partition(哈希分区)

4. Key partition(键值分区)

二、subparitioning(子分区)

三、分区的基本维护

一、分区的类型1. Range partition(范围分区)

Range partition是按照分区表达式的运算结果,判断结果落在某个范围内,从而将数据存储在对应的分区。各个分区定义之间需要连续且不能重叠,范围分区通过partition by range子句定义,而分区的范围通过values less than子句划分。

例:定义一个员工表,根据员工ID分区,110号员工一个分区,1120号员工一个分区,依次类推,共建立4个分区:

create table employees ( id int not null primary key, first_name varchar(30), last_name varchar(30)) partition by range(id)( partition p0 values less than (11), partition p1 values less than (21), partition p2 values less than (31), partition p3 values less than (41) );

现在随便插入几条数据:

insert into employees values(1,'Vincent','Chen');insert into employees values(6,'Victor','Chen');insert into employees values(11,'Grace','Li');insert into employees values(16,'San','Zhang');commit;

分区查询:

如果在查询时候明确的知道数据所在的分区,我们可以直接指定分区:

select * from employees partition(p0); -- 查询p0分区select * from employees partition(p0,p1); -- 查询p0和p1分区

分区删除:

如果某分区数据不再需要的时候,我们可以用alter table … drop partition来删除指定分区,例如删除分区p1,采用drop partition的方式可以快速清除历史数据:

alter table employees drop partition p1;

分区p1被删除后,所有p1分区的数据都已丢失,此时原p1分区的范围将由p2覆盖。

分区新增:

对于range分区来说,分区新增只能在最大范围之上增加分区,因此p1分区被删除后就无法通过新增分区的方式加回了,下例试图对ID10~20的员工新增一个分区,系统会返还错误。

alter table employees add partition (partition n1 values less than(21));

而在最大的分区范围之上是可以的:

alter table employees add partition (partition p4 values less than(51));

分区重组织:

如果一定要在分区之间插入新的分区,则可以采用重组织的方式,将已有分区的数据重新划分,达到创建新分区的效果:

例如我要将p2划分为2个分区,分别是1120,2130:

alter table employees reorganize partition p2 into (partition p1 values less than(21),partition p2 values less than(31));

此时原p2分区被拆分为了p1,p2,数据也在2个分区间重新分布,保证不会丢失。效果就像我们在中间插入了一个分区一样。

目前定义的分区都是有上限的,如果有大于分区上限的值想插入表中,系统会返还错误,为了兼容这种情况,我们可以新增一个分区,上限为maxvalue。所有大于当前上限的值都会放入这个分区:

alter table employees add partition(partition pmax values less than(maxvalue));

范围分区的条件除了直接用值,还可以用函数来定义。一个常用的场景就是按时间分区,例如:在create table中使用partition by range(year(hire_date)),可以按照年份来进行分区。这种分区方式在需要定期清理过期数据的场景会非常方便。

Range columns分区:

Range分区还有一个变种,叫做range columns分区。此分区方式允许使用多个column来作为分区范围条件。但是此分区方式不能接受函数,只能直接用列的名称。但是对分区列的类型不再限制为整数,可以使用string,date等类型。

使用range columns对多个列进行分区:

CREATE TABLE rc2 ( a INT, b INT)PARTITION BY RANGE COLUMNS(a,b) ( PARTITION p0 VALUES LESS THAN (0,10), PARTITION p1 VALUES LESS THAN (10,20), PARTITION p2 VALUES LESS THAN (10,30), PARTITION p3 VALUES LESS THAN (MAXVALUE,MAXVALUE) );

使用range columns直接对date类型进行分区:

CREATE TABLE members ( firstname VARCHAR(25) NOT NULL, lastname VARCHAR(25) NOT NULL, username VARCHAR(16) NOT NULL, joined DATE NOT NULL)PARTITION BY RANGE COLUMNS(joined) ( PARTITION p0 VALUES LESS THAN ('1960-01-01'), PARTITION p1 VALUES LESS THAN ('1970-01-01'), PARTITION p2 VALUES LESS THAN ('1980-01-01'), PARTITION p3 VALUES LESS THAN ('1990-01-01'), PARTITION p4 VALUES LESS THAN MAXVALUE);

Range partition和null:

对range分区来说,如果插入数据分区键为null,是可以成功的,数据会被放到第一个分区中。

2. List partition(列表分区)

列表分区和范围分区类似,主要区别是list partition的分区范围是预先定义好的一系列值,而不是连续的范围。列表分区采用partition by list和values in子句定义。

示例,创建一张员工表按照ID进行列表分区:

CREATE TABLE employees ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30))PARTITION BY LIST(id) ( PARTITION p0 VALUES IN (1,3,5,7,9), PARTITION p1 VALUES IN (2,4,6,8,10));

和range分区一样,可以使用alter table … add/drop partition新增/删除分区:

ALTER TABLE employees ADD PARTITION(PARTITION p2 VALUES IN (11,12,13,14,15));ALTER TABLE employees DROP PARTITION p0;

List partition和非事务引擎:

如果插入的值在list分区范围中不存在的话,语句会返还错误。如果表使用的是事务型引擎,如innodb。则这个事务会完全回滚。如果使用的是非事务引擎,若MyISAM,虽然也会报错,但是已插入的行无法回滚。

下面新建两张表,一张使用innodb,一张使用myisam:

CREATE TABLE employees_innodb ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30)) ENGINE=InnoDB -- 事务型引擎PARTITION BY LIST(id) ( PARTITION p0 VALUES IN (1,3,5,7,9), PARTITION p1 VALUES IN (2,4,6,8,10));CREATE TABLE employees_myisam ( id INT NOT NULL, fname VARCHAR(30), lname VARCHAR(30)) ENGINE=MyISAM -- 非事务型引擎PARTITION BY LIST(id) ( PARTITION p0 VALUES IN (1,3,5,7,9), PARTITION p1 VALUES IN (2,4,6,8,10));insert into employees_innodb values(1,'Vincent','Chen'),(11,'Grace','Li'),(2,'Victor','Chen');insert into employees_myisam values(1,'Vincent','Chen'),(11,'Grace','Li'),(2,'Victor','Chen');select * from employees_innodb;select * from employees_myisam;

MySQL分区表详解(mysql分区分表原理)

我们在中间放了一个不存在对应分区的记录来触发错误,可以看到innodb引擎数据没有数据插入(回滚)。但MyISAM引擎报错前的数据已经保留了下来,但是报错之后的记录未执行插入。

如果要忽略此错误,可以在insert语句中使用ignore关键字来忽略此错误,只插入符合分区条件的值:

insert ignore into employees_innodb values(1,'Vincent','Chen'),(11,'Grace','Li'),(2,'Victor','Chen');insert ignore into employees_myisam values(1,'Vincent','Chen'),(11,'Grace','Li'),(2,'Victor','Chen');

可以看到符合条件的记录被插入,不符合条件的自动被过滤,不返回错误。

List columns分区:

和range分区类似,list partition也有一个变种的list columns 分区,此分区类型可以使用多个列同时作为分区条件,且不再限制整数。并且可以使用string,date等数据类型作为分区条件。

list partition和null:

对于列表分区来说,必须有1个分区显示的指定可以包含null,否则插入会失败。

3. Hash partition(哈希分区)

Hash partition主要的应用场景是将数据平均的分布在指定数量的hash分区中。在range和list分区类型中,根据分区条件的计算结果,数据可以确定存储在哪个分区,而在hash分区中,数据存储在某个分区是由数据库自己决定的,你只需要指定分区的数量。

要创建hash分区,你需要使用create table的partition by hash(expr)子句,其中expr是整数类型的列或返还整数的表达式。另外还需要使用partions num来指定hash分区的数量(若忽略partitions子句则默认只创建1个hash分区)。

例:创建一个具有4个hash分区的表,按照ID进行分区:

CREATE TABLE employees ( id INT NOT NULL, first_name VARCHAR(30), last_name VARCHAR(30))PARTITION BY HASH(id)PARTITIONS 4;

Hash分区的性能考虑:

对于hash分区,数据库决定将数据存储在哪个分区是采用取余的方式进行运算的。存储分区的编号n = mod(expr, num),其中expr是分区值,num为定义的分区数量。

例如:对于4个hash分区,ID为5的记录,会存储在mod(5,4)=1,即1号分区中。

因此,最佳的分区键值的变化方式应该是线性变化,此时使用hash分区的效率最高,分布也会均匀。由于分区键值expr在每次insert/update/delete时都会运算,太复杂的表达式也会带来负面的性能影响,在选择时也需要考虑。

Liner hash partition(线性哈希分区):

以上的分区类型即普通hash分区,另外还有一类变种叫做liner hash partition(线性哈希分区),线性哈希分区的区别是其使用了更复杂的计算方法来确定数据的分布:

1. 对于分区数量为num的分区表,先计算V: V = POWER(2, CEILING(LOG(2, num)))2. 对于分区值与V-1进行位与运算 N = expr & (V - 1) -- 位与运算3. 对于N>num的情况,再次计算 N = N & ((v/2)-1)

例:假设分区数量为4

1. 先根据分区数量num计算V的值,先log再power,如果分区数量如果是2的次方,则此公式计算结果不变。

V = power(2,ceilling(log(2,4))) = power(2,ceillling(2)) = power(2,2) = 4

2. 对于ID为5的记录:

N = 5 & (V-1) = 5 & 3 = 1

3. 第二步计算出的结果为1,N<=num,不再需要第三步计算,数据存储在1号分区。

计算机的位计算效率是非常高的,因此Liner hash在新增/删除/合并/分裂分区场景(需要重新计算并分布数据)速度会快很多,非常适合特别大的数据存储场景(TB级别)。

Liner hash的缺点是数据的分布可能没有普通hash均匀。

管理hash分区数量:

Hash分区无法像range和list那样添加和删除分区,但是你可以用alter table的coalesce partition子句来减少hash分区的数量,用add partition partitions N来增加指定数量的分区。

例:将employees的hash分区数量由4调整为3:

ALTER TABLE employees COALESCE PARTITION 1; -- 移除一个分区

例:为employees表新增3个hash分区:

ALTER TABLE employees ADD PARTITION PARTITIONS 3; -- 新增3个hash分区

hahs partition和null:

对于hash partition和key partition,任何表达式对null运算,都会被当做返回为0.

4. Key partition(键值分区)

Key paritition与hash分区类似,主要区别在于key partition的hash函数是由MySQL server提供的,且使用主键(或非空唯一键)作为分区列:

例如:创建一个2个分区的key partition table:

CREATE TABLE k1 ( id INT NOT NULL PRIMARY KEY, name VARCHAR(20))PARTITION BY KEY() -- 未指定分区列,自动使用主键PARTITIONS 2;CREATE TABLE k1 ( id INT NOT NULL, -- 如果未定义not null,创建表会失败 name VARCHAR(20), UNIQUE KEY (id))PARTITION BY KEY() -- 未定义主键,自动使用unique keyPARTITIONS 2;

另外对于key partition,paritition key也不像其他分区类型那样限制为整数类型,例如,可以使用字符型作为分区键:

CREATE TABLE tm1 ( s1 CHAR(32) PRIMARY KEY -- 字符型主键,同时作为partition key)PARTITION BY KEY(s1)PARTITIONS 10;

对于key partition,由于primary key需要同时作为partition key,所以执行alter table … drop partition会报错(NDB引擎表会重组织并生成隐藏的primary key,不受此限制)。

mysql> alter table k1 drop primary key;ERROR 1488 (HY000): Field in list of fields for partition function not found in table-- 主键删除失败

Key partition和hash partition一样,也有liner key分区。

CREATE TABLE tk ( col1 INT NOT NULL, col2 CHAR(5), col3 DATE)PARTITION BY LINEAR KEY (col1) -- Liner key partitionPARTITIONS 3;

Key partition数量的管理方法与hash partition相同。

二、subparitioning(子分区)

subpartitioning可以在原有分区表的基础上,对每个分区再次进行分区(子分区)。子分区的分区类型可以和父分区不同,因此也叫复合分区。

下面的示例即对range partition的每个分区再次进行hash partition。父分区p0,p1,p2将各包含2个子分区,因此最终分区的数量为3*2=6个

CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) -- 父分区采用range partition SUBPARTITION BY HASH( TO_DAYS(purchased) ) -- 子分区采用hash partition SUBPARTITIONS 2 -- 子分区数量为2 ( PARTITION p0 VALUES LESS THAN (1990), PARTITION p1 VALUES LESS THAN (2000), PARTITION p2 VALUES LESS THAN MAXVALUE );

你也可以显示的定义每个子分区的名称,但如果采用这种方式定义,则必须显示指定所有子分区。且子分区的数量必须相同,子分区名称不能重复:

CREATE TABLE ts (id INT, purchased DATE) PARTITION BY RANGE( YEAR(purchased) ) --父分区为range partition SUBPARTITION BY HASH( TO_DAYS(purchased) ) --子分区为hash partition ( PARTITION p0 VALUES LESS THAN (1990) ( SUBPARTITION s0, -- 显式指定子分区名称和数量 SUBPARTITION s1 ), PARTITION p1 VALUES LESS THAN (2000) ( SUBPARTITION s2, SUBPARTITION s3 ), PARTITION p2 VALUES LESS THAN MAXVALUE ( SUBPARTITION s4, SUBPARTITION s5 ) );三、分区的基本维护

分区表的一大优势就是各个分区可以独立存储和管理。因此大部分在表级别上的管理操作都可以应该在分区上。

重建分区:

重建分区功能相当于清除分区中所有记录,然后在重新插入。对于频繁的更新的分区,可以定期使用重建的方式清除碎片。

ALTER TABLE employees REBUILD PARTITION p0, p1; -- 重建p0,p1分区ALTER TABLE employees REBUILD PARTITION ALL; -- 重建所有分区

检查分区:

你可以用check table语句来检查指定分区是否存在损坏:

ALTER TABLE employees CHECK PARTITION p1; -- 检查p1分区ALTER TABLE employees CHECK PARTITION all; -- 检查所有分区

键值分布统计:

使用alter table … analyze partition可以统计指定分区的键值分布,已便更好的生成执行计划:

ALTER TABLE employees ANALYZE PARTITION p0; -- 分析p0分区ALTER TABLE employees ANALYZE PARTITION ALL; -- 分析所有分区

分区修复:

使用alter table … repair partition来修复损坏的分区:

ALTER TABLE employees REPAIR PARTITION p0; -- 分析p0分区ALTER TABLE employees REPAIR PARTITION ALL; -- 修复所有分区

优化分区:

如果分区存在大量的数据更新,你可以使用optimize partition来回收空间,收集统计信息。其效果相当于在分区上执执行check partition、analyze partition 和 repair partition一样。

ALTER TABLE employees OPTIMIZE PARTITION p0;

但是对于innodb存储引擎来说,并不支持optimize partition操作,对单一分区执行会导致所有的分区都重建,谨慎使用(Table does not support optimize on partitions. All partitions will be rebuilt and analyzed.)。

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

本文链接地址:https://www.jiuchutong.com/zhishi/290867.html 转载请保留说明!

上一篇:阿尔卑斯山Cheran峡谷中流淌的河流,法国萨瓦 (© Jean-Philippe Delobelle/Minden)(阿尔卑斯山城市)

下一篇:Asian elephants in West Bengal, India (© Avijan Saha/Minden Pictures)

  • 扬州黄码转绿码怎么申请(扬州黄码转绿需3日内2次阴性)

    扬州黄码转绿码怎么申请(扬州黄码转绿需3日内2次阴性)

  • 财付通怎么关闭财付通支付(财付通怎么关闭在哪里关闭)

    财付通怎么关闭财付通支付(财付通怎么关闭在哪里关闭)

  • 支付宝账单如何查(支付宝账单如何批量删除)

    支付宝账单如何查(支付宝账单如何批量删除)

  • 红米note8pro发热严重(红米note8Pro发热太严重怎么办?)

    红米note8pro发热严重(红米note8Pro发热太严重怎么办?)

  • 苹果xs电池一年内免费换吗(iphonexs一年电池损耗)

    苹果xs电池一年内免费换吗(iphonexs一年电池损耗)

  • 计算机算什么学科门类(计算机算什么学科门类考研)

    计算机算什么学科门类(计算机算什么学科门类考研)

  • 闲鱼上卖书为什么便宜(闲鱼上卖书为什么这么贵)

    闲鱼上卖书为什么便宜(闲鱼上卖书为什么这么贵)

  • 电子邮件从本质上来说是什么(电子邮件从本质来说事)

    电子邮件从本质上来说是什么(电子邮件从本质来说事)

  • mt6737相当于骁龙多少(mtk6737t相当于骁龙多少)

    mt6737相当于骁龙多少(mtk6737t相当于骁龙多少)

  • 华为手机工厂在哪里(华为手机工厂在哪个城市)

    华为手机工厂在哪里(华为手机工厂在哪个城市)

  • 国外可以使用微信转账吗(国外可以使用微信吗)

    国外可以使用微信转账吗(国外可以使用微信吗)

  • 地图如何不显示文字(地图改位置怎么改)

    地图如何不显示文字(地图改位置怎么改)

  • vue怎么制作慢动作(vue怎么调慢动作速度)

    vue怎么制作慢动作(vue怎么调慢动作速度)

  • 新款ipadpro什么时候发布(ipad pro2022值得买吗)

    新款ipadpro什么时候发布(ipad pro2022值得买吗)

  • 笔记本不拆机怎么清灰(笔记本不拆机怎么加内存)

    笔记本不拆机怎么清灰(笔记本不拆机怎么加内存)

  • switch出厂带贴膜吗(switch出厂带膜吗)

    switch出厂带贴膜吗(switch出厂带膜吗)

  • 小米6x上市时间(小米6x什么时间出的)

    小米6x上市时间(小米6x什么时间出的)

  • 运费险在支付宝哪里看(运费险在支付宝哪里领取)

    运费险在支付宝哪里看(运费险在支付宝哪里领取)

  • 刷宝怎么兑换现金(刷宝怎么兑换现金红包)

    刷宝怎么兑换现金(刷宝怎么兑换现金红包)

  • 打95188可以解封花呗么(打95188有协商成功的吗)

    打95188可以解封花呗么(打95188有协商成功的吗)

  • 怎么解除快手评论上限(怎么解除快手评论禁言)

    怎么解除快手评论上限(怎么解除快手评论禁言)

  • linux中yum update被占用(Another app is currently holding the yum lock)的解决办法(linux yum update)

    linux中yum update被占用(Another app is currently holding the yum lock)的解决办法(linux yum update)

  • hcontrol.exe是什么进程 作用是什 hcontrol进程查询(hhcol.exe)

    hcontrol.exe是什么进程 作用是什 hcontrol进程查询(hhcol.exe)

  • 扩散模型 (Diffusion Model) 简要介绍与源码分析(扩散模型和gan的区别)

    扩散模型 (Diffusion Model) 简要介绍与源码分析(扩散模型和gan的区别)

  • 增值税属于哪个部门
  • 未确认融资费要还款吗
  • 企业的承兑汇票贴息很高说明什么
  • 定金冲抵货款怎么做分录
  • 小规模企业开具普通发票月如何做账
  • 事业单位不用纳税吗
  • 小企业出租设备分录
  • 实物投资账务处理
  • 银行存款日记账与银行对账单之间的核对属于
  • 私人出租房子发票怎么开
  • 企业工资薪酬包括哪些内容
  • 小规模企业申请破产流程
  • 新三板公司股东人数
  • 制造费用月末需要结转吗
  • 专项储备期末有余额吗
  • 汇算清缴发票可以做费用票吗
  • 留用员工培训费怎么入账
  • 出口货物免抵退税额确认会计分录
  • 事业单位 年终
  • 报销招待费的会计怎么做
  • 报税残疾人保障金怎么算
  • 工资只发一半
  • 印花税的征收范围
  • win 10有什么用
  • windows 11预览版
  • ghost打开
  • 魅族路由器mini说明书
  • proxydriod
  • php如何读取文件内容
  • 计算机视觉会议2023年11月
  • php5.6+mysql
  • 小刺猬 (© lorenzo104/Getty Images)
  • 小规模报税系统登录
  • pytorch如何训练模型
  • Yii2中hasOne、hasMany及多对多关联查询的用法详解
  • 什么情况下可以赔偿n+1
  • 已抄报未反写什么意思
  • php use关键字
  • 老师不干了可以从事什么行业
  • ai当前的发展
  • lftp shell
  • nginx运行python
  • 中药饮片盘点误差范围
  • 织梦模板安装完整教程
  • MongoDB的mongo shell常用操作方法及操作脚本笔记
  • 房产税中出租房产原值怎么算
  • 电子发票如何申领取电子发票
  • 个税申报怎样作废
  • 发票备注栏必须写吗
  • sqlserver 删除数据
  • 投资性房地产转为存货
  • 食堂辅助账的账务处理
  • 其他收益会计科目解释
  • 劳动保护费进什么科目
  • 零余额账户银行日记账
  • 提取坏账会计分录怎么写
  • 进项做成了销项怎么调账
  • 建账的注意事项
  • 清除sql表内容
  • centos基本操作
  • dvd-rom drive是什么意思
  • Mac系统中使用QuickTime Player实现屏幕录像图文教程
  • win10系统电脑无法开机怎么办
  • fpd文件是什么意思
  • win7麦克风不好使
  • win8怎么查ip地址查询
  • js如何使用
  • opengl 有哪些特点?与directx相比它有什么不同?
  • vue2里面ref的具体使用方法
  • bat注销命令
  • 猫的游戏解说
  • apktool修改包名
  • 详解TCP的四种定时器
  • 有关javascript的书
  • 如何终止promise
  • JavaScript基础语法详解
  • jquery22插件网
  • 在python中的用法
  • 国家税务总局可以设定行政处罚吗
  • 单位固定资产转到个人名下要交税吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设