INNODB引擎学习-分区表(-)

分区表

    Mysql5.1版本时,添加了分区支持。分区的过程是将一个表或索引分解成更小,更可管理的部分。
    
    Mysql的分区是水平分区,并不支持垂直分区。Mysql数据是局部分区索引,一个分区中既有索引又有数据。而全局分区索引,则是分区中只有数据,但是所有的索引都放在一个对象中。
    目前Mysql不支持全局分区索引。
   
    查看数据库是否启动了分区功能:SHOW PLUGINS;
    
    Mysql支持的几种分区类型:
    
        □ RANGE分区:行数据基于属于一个给定连续区间的列值被放入分区。MySQL 5.5开始支持RANGE COLUMNS的分区。
        □ LIST分区:和RANGE分区类型,只是LIST分区面向的是离散的值。MySQL 5.5开始支持LIST COLUMNS的分区。
        □ HASH分区:根据用户自定义的表达式的返回值来进行分区,返回值不能为负数。
        □ KEY分区:根据MySQL数据库提供的哈希函数来进行分区。
        
    不论创建何种分区,如果表中存在主键或唯一索引,则分区列必须是唯一索引的组成部分。如果没有指定的主键或者唯一索引,则分区列可以指定为任何一列。
    
    1、RANGE分区
    
        语法示例:
    
            create table t(
                id INT
            )ENGINE=InnoDB
            PARTITION BY RANGE(id)(
            PARTITION P0 VALUES LESS THAN (10),
            PARTITION P1 VALUES LESS THAN (20)
            )
        注:以id为分区列,小于10的存储在P0,大于等于10小于20存储在P1,如果写入的数据大于等于20会报错。
        
        针对大于等于20的情况,我们可以添加一个分区,上限是无穷大
        
        语法:
        
        ALTER  TABLE t ADD PARTITION(
            PARTITION P2 VALUES LESS THAN MAXVALUE
        )
        
        RANGE分区主要是针对日期列,比如销售类,以日期分区
        
            create table t_time(
                date datetime
            )ENGINE=InnoDB
            PARTITION BY RANGE(YEAR(date))(
            PARTITION P2008 VALUES LESS THAN (2009),
            PARTITION P2009 VALUES LESS THAN (2010),
            PARTITION P2010 VALUES LESS THAN (2011)
            )
            
        select date from t_time where date>='2008-01-01' and date<='2008-12-31'


        select date from t_time where date>='2008-01-01' and date<'2009-01-01'


       注:Mysql技术内幕-Innodb引擎第二版中说,该两条语句用到的分区会不一样,实际验证有差异,语句都只用到P2008一个分区,因此两条语句查询效率一样
        此外分区更方便管理,如果需要删除2008年月份的数据,只需要删除P2008分区即可。

语法为:alter table t_time drop partition P2008。


        查询计划的语法:explain partitions select date from t where date>='2008-01-01' and date<='2008-12-31';
        
        再来说下针对日期的特殊情况,比如我想按照精细到月份进行分区,因此我这么写
            create table t(
                date datetime
            )ENGINE=InnoDB
            PARTITION BY RANGE(YEAR(date)*100+MONTH(date))(
            PARTITION P200801 VALUES LESS THAN (200801),
            PARTITION P200802 VALUES LESS THAN (200802),
            PARTITION P200803 VALUES LESS THAN (200803)
            )
            
        然后插入示例数据之后,你通过查询计划去看,发现分区的优势并没有体现出来,三个分区始终是会用到。这是什么原因呢??
        
        产生这个问题的主要原因是因为是对于RANGE分区的查询,优化器只能对YEAR(),TO_DAYS(),TO_SECONDS(),UNIX_TIMESTAMP()
        这类函数进行优化选择,因此对于上述的要求,需要将分区函数改为TO_DAYS,如:
            create table t(
                date datetime
            )ENGINE=InnoDB
            PARTITION BY RANGE(TO_DAYS(date))(
            PARTITION P200801 VALUES LESS THAN (TO_DAYS('2008-02-01')),
            PARTITION P200802 VALUES LESS THAN (TO_DAYS('2008-03-01')),
            PARTITION P200803 VALUES LESS THAN (TO_DAYS('2008-04-01'))
            )

2、List分区

      LIST分区和RANGE分区非常相似,只是分区列的值是离散的,而非连续的。

     不同于RANGE分区中定义的VALUES LESS THAN语句,LIST分区使用VALUES IN。因为每个分区的值是离散的,因此只能定义值

示例:

            create table t_1(
                     id INT
             )ENGINE=INNODB
                PARTITION BY LIST(id)(
                PARTITION a values in (1,3,5,7),
                PARTITION b values in (2,4,6,8)
              )

     针对List分区如果插入的数组,未包括在分区定义内,Innodb引擎会报错,然后事务回滚。示例:

      

扩展:MyISAM引擎会将报错之前的行数据都插入,但之后的数据不会被插入。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值