《深入浅出Mysql》阅读梳理 四

点击查看合集

事务控制

开启事务:start transaction
回滚到事务开始的地方:RollBack
添加保存点:SavePoint point1 (同名保存点,后创建的会覆盖先创建的。删除保存点: release SavePoint point1 )
回滚到保存点:RollBack To point1
提交事务:Commit
commit and chain:提交事务后,马上开启一个新事务
commit release 或者commit work :提交事务后断开与客户端的连接。

MySQL分区

分区有利于管理非常大的表,他采用了分而治之的逻辑。分区引入了分区键的概念,分区键用于根据某个区间值(或者范围)、特定值列表或者Hash函数值执行数据的聚集。让数据根据规则分布在不同的分区中。让一个大对象变成许多小对象。

MySQL分区的优点

1.和单个磁盘或者文件系统分区相比,可以存储更多的数据
2.优化查询。在where字句中包含分区条件时,可以只扫描必要的1个或几个分区。count(*)函数可以并发执行再汇总结果
3.对于已经过期或者不需要保存的数据,可以通过删除与这些数据相关的分区来删除这些数据
4.跨多个磁盘来分散数据查询,以获得更大的查询吞吐量。

分区类型

1.Range分区:基于一个给定连续区间范围,把数据分配到不同的分区。
2.List分区:类似Range分区,区别在于List分区是基于枚举出的值列表分区,Range是基于给定的连续区间范围分区
3.Columns分区:类似于Range和List,区别在于分区键既可以是多列又可以是非整数
4.Hash分区:基于给定的分区个数,把数据取模分配到不同的分区
5.Key分区:类似于Hash分区,但使用MySQL提供的哈希函数
6.子分区:也叫做复合分区或者组合分区,即再主分区下再做一层分区,将数据再次分割。
在Mysql 5.7中除了Key分区和Columns分区其他的分区都必须是int类型。
不能使用主键或者唯一键之外的键作为分区键,除非没有主键或者唯一列。

Range分区

例子

create table test7(
	id int
)
Partition BY Range(id) (
	Partition p0 Values Less Than (10),
	Partition p1 Values Less Than (20),
	Partition p2 Values Less Than (30)
)

用id作为分区键分了三个区。分别是小于10、[10,20) [20,30)。如果插入30的话将会报错。
而且就像switch case 语句一样这三个不能调换顺序

Insert into test7 VALUES(30)
> 1526 - Table has no partition for value 30
> 时间: 0s

因为没有规定大于等于30的数据存在哪里。因此只需要加上即可。可以通过下列语句添加大于等于30的数据为一个分区

Alter Table test7 add Partition(Partition p3 Values Less Than(MAXVALUE))
> OK
> 时间: 0.037s

在执行插入语句

Insert into test7 VALUES(30)
> Affected rows: 1
> 时间: 0.003s

如果使用了Values Less Than (MAXVALUE)后又想要添加分区的话。只能重新建立分区了

Alter Table test7 Partition BY Range(id) (
	Partition p0 Values Less Than (10),
	Partition p1 Values Less Than (20),
	Partition p2 Values Less Than (30)
)
> OK
> 时间: 0.172s

分区键也支持表达式(例如 Year(日期))
Mysql从5.5版本开始,改进了Range分区功能,提供了Range Columns分区,此分区方式支持非整数分区。

Range分区适用环境

1.当需要删除过期的数据时,只需要简单的Alter Table test7 Drop Partition p0.就可以删除p0分区的数据了
2.经常运行包含分区键的查询。Mysql可以很快确定要查找的数据在哪几个分区

List分区

创建List分区

create table test8(
	id int
)
Partition BY List(id) (
	Partition p0 Values in (1,2,3),
	Partition p1 Values in (4,5,6),
	Partition p2 Values in (10)
)
> OK
> 时间: 0.062s

List分区中没有类似Range分区中的Values Less Than (MAXVALUE)的可以代表其他所有值的方式。所有情况都必须要在列表中存在。
如果想要定义非整数的List。可以使用List Columns。
其他操作与Range类似

Columns分区

Columns可以细分为List Columns和Range Columns
例子

create table test9(
	id int,
	idd int
)
Partition BY List Columns(id,idd)
 (
	Partition p0 Values in ( (1,2021) ,(11,3021),(11,31021)  ),
	Partition p1 Values in ( (2,2023) ),
	Partition p2 Values in ( (3,2022))
)
> OK
> 时间: 0.065s
create table test10(
	id int,
	idd int
)
Partition BY Range Columns(id,idd)
 (
	Partition p0 Values Less Than(10,10),
	Partition p1 Values Less Than(10,20),
	Partition p2 Values Less Than(MAXVALUE,MAXVALUE)
)
> OK
> 时间: 0.059s

注意:
Columns的分区键不能是表达式
Range Columns的第一个分区键必须按顺序,不能交叉。
Columns可以使用非整数作为分区键。可以使用的类型有
整数型:tinyint smallint mediumint int bigint
日期时间类型:date datetime
字符类型:char varchar binary varbinary

Hash分区

Hash分区又可以细分为常规Hash分区和线性Hash分区
常规Hash分区是通过取模运算计算分区。
常规Hash分区例子

create table test11(
	id int
)
Partition BY Hash(id) Partitions 10
> OK
> 时间: 0.196s

id为分区键,分10个区。如果id = 0则在p0分区。如果id 为11则在p1分区(取模运算)
如果要添加分区的话,就要更改分区数。这样的话之前的数据就要更换分区。这样将会带来巨大的开销。
如果使用线性分区的话在分区维护(增加 删除 合并 拆分分区)时,Mysql能够处理的更加迅速。但是线性分区相较于常规Hash分区的话数据分布不均匀。
线性分区是通过2的幂算法得到的
线性分区的语句只需要在Hash(id)前面加一个linear 即

create table test12(
	id int
)
Partition BY Linear Hash(id) Partitions 10
> OK
> 时间: 0.184s

Hash分区的分区键只能是整形,可以使用表达式

Key分区

Key分区和Hash分区非常相似,也有Liner Key。
Key分区可以指定0个或多个键作为分区键。
当指定为0时,会默认指定主键作为分区键。如果没有主键则指定非空唯一键作为分区键。如果都没有的话则不能为0.
key分区可以使用除了Blob和Text以外的所有数据类型作为分区键
例子

create table test13(
	id int
)
Partition BY Key(id) Partitions 10
> OK
> 时间: 0.227s

子分区

子分区是对分区再分区的操作。现在已经支持对Range和List和Columns分区进行子分区
每个分区具备相同数量的子分区。
如果要显示创建子分区,那么每个分区都要显示创建
可以用Key Linear Key或者Hash Liner Hash创建子分区
隐式创建子分区

create table test14(
	id int
)
Partition BY List Columns(id)
SubPartition BY Linear Key(id) SubPartitions 10
(
	Partition p0 Values in (12)
)

显式创建子分区

create table test15(
	id int
)
Partition BY List Columns(id)
SubPartition BY Linear Key(id) 
(
		Partition p0 Values in (12)(
			SubPartition sp0,
			SubPartition sp1
		),
		Partition p1 Values in (13)(
			SubPartition sp2,
			SubPartition sp3
		)
)
> OK
> 时间: 0.075s

MySQL分区处理NULL值得方式

MySQL不禁止分区键为NULL。NULL一般表示为最小值或者零值
在Hash Key分区中NULL作为0值。在LIst分区中需要在列表中枚举NULL。在Range表中作为最小值。

分区管理

MySQL提供了添加 删除 重定义 合并 拆分 交换分区的命令,这些操作都可以通过Alter Table3命令来实现

Range和List的分区管理

他俩的分区管理非常相似。

重定义

Alter table 表名 Partition By Range/List(分区键) (Partition Values.....)

添加

Alter Table 表名 add Partition(Partition 分区名 Values XXX)

Range分区只能从最右端添加,List不能添加重复值

删除

Alter Table 表名 Drop Partition 分区名 #删除数据
alter table 表名 Remove Partitioning #不删除数据

同时删除分区中的数据

重组

Alter Table 表名 Reorganized Partition 分区名 into(
	Partition 分区名 Values....,
	Partition 分区名 Values....
) #拆分

Alter Table 表名 Reorganized Partition 分区名,分区名 into(
	Partition 分区名 Values....,
) #重组

Range和List拆分必须和之前覆盖相同的分区。重组只能重组相邻分区。重定义分区不能更改分区类型

Hash和Key 分区管理

重定义

Alter table 表名 Partition By Hash/Key(分区键) Partitions n

合并分区

Alter Table 表名 Coalescs Partition num #num为减少num个分区

增加分区

alter table 表名 add Partition Partitions num#num为增加num个分区

删除

alter table 表名  remove Partitioning#不删除数据

交换分区

Alter Table pt Exchange Partition p With Table nt

可实现将分区表pt中的一个分区或者子分区p与普通表nt进行数据交换
但是需要满足下列条件
1.表nt不能是分区表。如果实现分区表交换,可以增加一个中间表,通过两次交换完成
2.表nt不能是临时表
3.表pt和nt的结构要完全一样。包括索引的名称和索引的列都要一样(create table t1 like t2 ; alter table t1 remove Partitioning)
4.表nt上不能有外键,也不能有外键引用nt
5.nt表上的所有数据都应在分区p的范围内

注意:
1.交换分区不会触发任何触发器
2.表中自增列的值会被重置
3.交换分区命令中Ignore关键字不会产生影响

猜你喜欢

转载自blog.csdn.net/qq_30033509/article/details/114445137