mysql分区之RANGE类型

目录

首先查看MySQL是否支持分区

在实际操作分区前我们得了解下分区的几点限制:

子分区的建立需要注意以下几个问题:

RANGE分区实操

SQL如何查询分区数据


首先查看MySQL是否支持分区

show  plugins;

 

 当查询结果显示partition的状态为active则表示当前MySQL版本支持分区。分区方案一般有四种:

  1.  RANGE分区:RANGE分区主要用于日期列的分区,是基于连续区间的列值来进行分区的。RANGE分区也是最常用的分区方式。
  2. LIST分区:LIST分区列的值是散列的,也正是由于分区列的值是散列的所以需要手动定义分区列的值。
  3. HASH分区:HASH分区就是通过自定义算法将数据均匀分布到不同分区,保证所有分区中数据大致相同。HASH分区只支持整数分区。
  4. KEY分区:key分区使用数据库自带函数进行分区。KEY分区可支持BLOBTEXT列之外的数据列分区。 

由于RANGE分区是最常用的分区方案,其他三种分区方案用的相对很少。这里主要介绍RANGE方案。

在实际操作分区前我们得了解下分区的几点限制:

  1.  数据表分区上限最多只能有1024个分区(mysql5.6之后支持8192个分区)。
  2. 同一个表的所有分区必须使用相同存储引擎。
  3. 数据库使用分区则不能使用外键约束,会报错。 
  4. 如果分区字段中有主键或者唯一索引列,那么所有主键列和唯一索引列都必须包含进来,如果表中有主键或唯一索引,那么分区键必须是主键或唯一索引。
  5. mysql数据库支持的分区类型为水平分区,并不支持垂直分区,因此,mysql数据库的分区中索引是局部分区索引,一个分区中既存放了数据又存放了索引,而全局分区是指的数据库放在各个分区中,但是所有的数据的索引放在另外一个对象中
  6. 目前mysql不支持空间类型和临时表类型进行分区。不支持全文索引
  7. 在mysql5.1中分区表达式必须是整数,或者是返回整数的表达式,在5.5之后,某些场景可以直接使用字符串列和日期类型列来进行分区(使用varchar字符串类型列时,一般还是字符串的日期作为分区)。

子分区的建立需要注意以下几个问题:

  1. 每个子分区的数量必须相同
  2. 只要在一个分区表的任何分区上使用subpartition来明确定义任何子分区,就必须在所有分区上定义子分区,不能漏掉一些分区不进行子分区。
  3. 每个subpartition子句必须包括子分区的一个名字
  4. 子分区的名字必须是唯一的,不能在一张表中出现重名的子分区
  5. mysql数据库的分区总是把null当作比任何非null更小的值,这和数据库中处理null值的order by操作是一样的,升序排序时null总是在最前面,因此对于不同的分区类型,mysql数据库对于null的处理也各不相同。对于range分区,如果向分区列插入了null,则mysql数据库会将该值放入最左边的分区,注意,如果删除分区,分区下的所有内容都从磁盘中删掉了,null所在分区被删除,null值也就跟着被删除了。在list分区下要使用null,则必须显式地定义在分区的散列值中,否则插入null时会报错。hash和key分区对于null的处理方式和range,list分区不一样,任何分区函数都会将null返回为0.

RANGE分区实操

按照RANGE分区的表是通过如下一种方式进行分区的,每个分区包含那些分区表达式的值位于一个给定的连续区间内的行。 

CREATE TABLE order_info (
id int not NULL PRIMARY KEY auto_increment,
goods_title VARCHAR(50) NOT NULL,
created_at date
) 
PARTITION BY RANGE (id) (
PARTITION order1 VALUES less than (10),
PARTITION order2 VALUES less than (20),
PARTITION order3 VALUES less than (30),
PARTITION order4 VALUES less than (40),
PARTITION order5 VALUES less than (50)
);

 创建一张order_info表并创建了5个分区,接下来我们查看order_info表分区情况,看是否成功形成5个分区:

SELECT partition_name part,
partition_expression expr,
partition_description descr
,table_rows FROM information_schema.`PARTITIONS` 
WHERE table_schema=SCHEMA() AND table_name='order_info';

  

可以看到上面的创建分区我们使用values less than语句,我们将id<10的数据保存在order1分区,将id范围在10-20保存在order2分区,以此类推创建了五个分区。

现在我们可以写个存储过程插入50条数据测试下: 

CREATE PROCEDURE test010()
BEGIN
DECLARE i INT;
SET i=1;
START TRANSACTION;
WHILE i<=50 DO
	INSERT INTO order_info VALUES(NULL,'测试数据',NOW());
SET i=i+1;
END WHILE;
COMMIT;
END
//
delimiter;
CALL test010();

 可以明显看到报错了,报没有分区可以存放id为50的值的错误信息。因为我们设置的第五个分区范围为40-50,右边不包含,所以超过50直接报错无法存放。这很不合理,所以说我们得对分区做一下调整  

我们使用alter table命令新增分区order6保存大于50的值:

ALTER TABLE order_info ADD PARTITION(PARTITION order6 VALUES less than (MAXVALUE));

  

 我们增加了order6分区,值设置为maxvalue,表示如果值大于order5设置的上限则保存进入order6分区。

我们插入500条数据到数据库中测试下效果:

   

我们查看下分区下各自含有几条数据 

   

我们可以看到完全按照我们设置的分区进行数据存放到不同的分区。可能有人会说我怎么确认order1分区存放的9条数据一定是id为1-10的呢?
这个其实测试很简单,我们直接删除order1分区,然后查看数据库数据: 

ALTER TABLE order_info DROP PARTITION order1;

   

        可以看到我们删除掉order1分区之后,id10以下的数据也跟着被删除了,所以可以表示id在10以下的确实保存在分区order1中。而我们完全可以按照时间来进行分区,然后将半年以上的数据移到备用表然后删除分区,这样就可以提高我们单表的性能。在删除数据时直接删除分区会远远比delete数据效率高很多。 

SQL如何查询分区数据

在进行select/update/delete时如果where后面的限制条件包含分区字段id时会自动去对应分区中查找,否则还是全表扫描。

EXPLAIN SELECT * FROM order_info WHERE id = 20;

可以看到上图只查询了 order3 分区。

EXPLAIN SELECT * FROM order_info WHERE goods_title = '测试数据2';

 可以看到上图查询了 order2,order3,order4,order5,order6分区,共查询了491行

range分区字段只支持整型,如果需要对时间日期这样的字段进行range分区,可以通过相关函数将类型转为整型再分区。 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MySQLRANGE 分区是一种分区类型,允许你根据给定的分区键范围将表分成多个不同的分区。这意味着,你可以指定多个值域,并为每个值域创建一个分区。在插入新行时,MySQL 会根据分区键的值将行存储到适当的分区中。 例如,假设你有一张名为 `sales` 的表,其中包含销售日期和销售额两个列。你可以使用 RANGE 分区将这张表分成几个不同的分区,每个分区包含一个时间段内的销售数据。 下面是一个使用 RANGE 分区的示例: ``` CREATE TABLE sales ( date DATE, amount DECIMAL(10,2) ) PARTITION BY RANGE (YEAR(date)) ( PARTITION p0 VALUES LESS THAN (2000), PARTITION p1 VALUES LESS THAN (2010), PARTITION p2 VALUES LESS THAN (2020), PARTITION p3 VALUES LESS THAN MAXVALUE ); ``` 这条语句会创建一张名为 `sales` 的表,该表被分成 4 个分区,分别对应日期在 2000 年之前、2000 年至 2010 年之间、2010 年至 2020 年之间、2020 年之后的销售数据。 ### 回答2: MySQLRANGE分区是一种在表中按照某个列的范围进行分区的方法。分区是将表中的数据按照一定的规则分割成多个独立的部分,每个部分称为一个分区RANGE分区是根据指定的列的取值范围来进行分区的。 在使用RANGE分区时,我们需要先定义分区函数,指定一个列作为分区键。然后可以根据这个列的范围来划分不同的分区,每个分区可以有自己独立的存储和索引。 例如,我们可以使用RANGE分区将一个订单表按照订单金额的范围进行分区。可以定义分区函数为根据订单金额,范围分为低价订单、中价订单和高价订单三个分区分区函数可以使用多种方式定义,包括使用整型、浮点型、日期型等等。 当我们插入新的订单数据时,系统会根据分区函数将新的数据插入到对应的分区中。这样,相同范围内的订单数据就可以放到同一个分区中,提高数据的查询效率。 同时,RANGE分区也提供了一些其他的灵活选项,如合并相邻的分区、添加新的分区等。这些操作可以帮助我们进行分区的优化和管理。 总的来说,RANGE分区是一种非常有用的MySQL分区方法。通过合理的定义分区函数,将数据按照某一列的取值范围进行划分,可以提高查询效率和管理数据的灵活性。 ### 回答3: MySQLRANGE分区是一种根据某个范围值将表分成多个分区的技术。在RANGE分区中,可以选择一个列作为分区依据,并根据该列的值的范围将表数据分成若干个分区RANGE分区的创建需要指定分区键,即用于分区的列。在创建表时,可以使用PARTITION BY RANGE(column)语法来指定分区列。然后,通过指定各个分区的范围值来定义分区。例如,可以使用PARTITION p0 VALUES LESS THAN (100)来定义一个分区范围,表示该分区所包含的数据的分区键值必须小于100。 使用RANGE分区可以实现数据的分布和查询的优化。分区可以根据数据的范围进行划分,使得相同范围的数据在同一个分区中,提高了查询效率。另外,对于某些特定的查询,可以仅对分区内的数据进行扫描,减少了扫描的数据量,进一步提高了查询性能。 RANGE分区还提供了一些管理分区的灵活性。可以通过增加或删除分区来控制数据的增长和存储的使用情况。还可以通过对不同分区采用不同的存储引擎来进一步优化性能。 总之,RANGE分区是一种将表数据按范围划分为多个分区的技术。它提供了优化查询性能、管理数据增长和灵活性等多种好处。在设计和使用数据库时,可以根据实际需求选择是否使用RANGE分区来提高系统的性能和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值