1.何为RANGE分区?
顾名思义,范围分区,它是根据列值的范围进行分区的。
2.实例学习
首先,创建一张表,并为表新建范围分区:
CREATE TABLE t(
id INT
)
PARTITION BY RANGE(id)(
PARTITION p0 VAlUES LESS THAN(10),
PARTITION p1 VALUES LESS THAN(20)
);
其中,建表语句后的:
1)建表时的范围分区创建语句:
PARTITION BY RANGE (id)(
PARTITION p0 VAULES LESS THAN(10),
PARTITION p1 VALUES LESS THEN(20)
);
它表示将t表设置成分区表,分区规则是范围分区,将表数据分为两部分,p0分区负责存储列id小于10的数据,p1分区负责存储列id为10到20的数据。这就是范围分区。
我们从前面学习到分区的原理其实就是:将一个表或索引分解成多个更小,更可管理的部分,从逻辑上说,只有一个表,但是从物理上说,这个表或索引可能由多个物理文件组成,每个分区都是独立的对象,可以独自处理。
所以我们在创建这张表后,查看其物理文件,会发现表不再由一个ibd文件组成,而是由建立各分区ibd组成,如图:
然后向此表插入数据:
INSERT INTO t values(9);
INSERT INTO t values(10);
INSERT INTO t values(15);
注意:对于表t,我们定义了分区,因此插入的值应该严格遵守分区的定义,当插入一个不在分区中定义的值时,MySQL数据库就会抛出一个异常,如:
INSERT INTO t values(20);
就会抛出一个异常:
而对于上述问题,也就是超过分区上限的值该如何存储,答案就是新加一个MAXVALUE(无穷大)值的分区:
ALTER TABLE t ADD PARTITION(
PARTITION p2 values less than maxvalue
);
成功插入!!
接着可以查看每个分区的一些属性信息:
2)查看表中每个分区的具体信息
SELECT * FROM information_schema.PARTITIONS
WHERE table_schema=database() AND table_name='t' \G;
从这里可以查看到每个分区的情况。
3.RANGE分区的主要应用场景
RANGE分区主要用于日期列的分区,例如,对于销售类的表,可以根据年份来分区存放销售记录。如下:
新建一张名为sales的表:
CREATE TABLE sales(
money int unsigned not null,
date datetime
)
partition by range(year(date))(
partition p2008 values less than(2009),
partition p2009 values less than(2010),
partition p2010 values less than(2011)
);
注意,这里的range(year(date))的原因是:RANGE,LIST,HASH,KEY四种分区种,分区的条件必须是整型!!,如果不是整型,那么需要通过函数将其转化为整型。 如YEAR(),TO_DAYS()…
接着向表种插入数据:
INSERT INTO sales(money,date)values(100,'2008-01-01');
INSERT INTO sales(money,date)values(100,'2008-02-01');
INSERT INTO sales(money,date)values(100,'2008-01-02');
INSERT INTO sales(money,date)values(100,'2009-03-01');
INSERT INTO sales(money,date)values(100,'2010-03-01');
1)方便删除
创建一个分区的好处就是,如果我们想删除一个分区的数据,无需重复执行delete语句,只需下面sql就可以清空分区数据:
ALTER TABLE table_name TRUNCATE PARTITION p_name;
如果我们以后不用该分区,也可以使用下面语句删除该分区达到删除效果:
alter table table_name drop partition p_name;
但这样做的坏处是分区不可复用。所以第一个删除语句是首选。
2)方便查询
使用分区,在范围查询中可以明显加快查询。
例如:
EXPLAIN SELECT * FROM sales where date>='2008-01-01' and date<='2008-12-31'
可以看到,使用到了分区查询而不是全表扫描!!!
注意:对于RANGE分区的查询,优化器只能对YEAR(),TO_DAYS(),TO_SECONDS()这类的函数进行优化选择,而不能对复合表达式进行优化选择!!