zoukankan      html  css  js  c++  java
  • MySQL表分区

    一、表分区partition

    指根据一定的规则,数据库把一个表分解成更多个小的、更容易管理的部分。逻辑上只有一个表或者一个索引,但实际上这个表可能由数个10个物理分区对象组成,每个分区都是一个独立的对象,可以独自处理,可以作为表的一部分进行处理。

    注意:

    同一个分区表的所有分区必须使用同一个存储引擎,但是对于不同的分区表可以使用不同的存储引擎。

    不能只对表数据分区而不对索引分区,反之亦然。

    # 查看是否支持分区

    Show variables like ‘%partition%’

    Show plugins 命令 查看是否安装分区插件等信息

    当一张表的数据非常多的时候,比如单个.myd文件都达到10G, 这时,必然读取起来效率降低.

    可不可以把表的数据分开在几张表上?

    1: 从业务角度可以解决. (分表)

    比如, 通过id%10 , user0 , user1....user9, 这10张表

    根据不同的余数,来插入或查询某张表.

    2: 通过mysql的分区功能

    mysql将会根据指定的规则,把数据放在不同的表文件上.

    相当于在文件上看,被拆成了数小块.

    但是,给客户的界面,还是1张表.

    常用的规则:

    根据某列的范围来分区, 也可以某列的散点值来分区.

    示例: 按列的范围来分区

    以用户表为例, uid

    uid [1,10)  ---> user partition u1

    uid[10, 20) ---> user partition u2

    uid [20, MAX] --> user partion u3

    二、分区类型

    Rangelist hash key分区

    无论哪种分区类型,要么分区表上没有主键/唯一键,要么分区表的主键/唯一键都必须包含分区键,也就是说不能使用主键/唯一键字段之外的其他字段分区

    5.1版本rangelisthash分区都要求分区键必须是int类型,或者通过表达式返回int类型,唯一例外的是key分区,可以使用其他类型的列(bolbtext列类型除外)作为分区键。

     

    5.5以上版本中,已经支持非整数的range分区和list分区,新支持的columns分区细分为 range columns 分区和 list columns 分区,都支持整数、日期时间、字符串三大数据类型。

    range分区

           利用取值范围将数据分区,基于一个给定连续区间范围,把数据分配到不同的分区,区间要连续并且不能互相重叠,使用values less than操作符进行分区定义values less than maxvalue子句提供给所有大于明确指定的最高值的值,maxvalue表示最大的可能的整数值。

    range分区键如果是null值会被当做一个最小值来处理。

    每个分区都是按顺序进行定义,从最低到最高。

     

    partition by range columns(uname)  # 提供range columns分区支持非整数分区

     

    create table emp(

         uid int auto_increment primary key,

         uname varchar(30)

     )engine myisam charset=utf8

    partition by range(uid) (

          partition u1 values less than (10),

          partition u2 values less than (20),

          partition u3 values less than MAXVALUE

     );

     

    适用情况:

    1. 删除过期数据, alter table emp drop partition u1 来删除u1分区中的数据,大数据下比delete来的快。
    2. 经常运行包含分区键的查询,可以很快的确定只有某一个或某些分区需要扫描

    Explain partitions select statement

    按散点list值分区

           类似range分区,区别在list分区是基于枚举出的值列表分区,即特定的值属于哪个分区,而range是基于给定的连续区间范围分区;

    partiton by list (expr)子句实行,expr是某列值或一个基于某列值返回一个整数值的表达式,然后通过values in (value_list) 的方式来定义分区,其中value_list是一个逗号分隔的整数列表。

    partiton by list columns (expr)  #支持非整数分区

    create table emp_list (

          uid int,

          pid int,

          uname varchar(30)

    )engine myisam

    partition by list(pid) (

          partition bj values in (1),

          partition ah values in (2),

          partition xb values in (4,5,6)

    );

    注意:

    在使用分区的时候,注意,分区的那个列,值不要为NULL (如果不小心为NULL,mysql为理解为0,尽量执行之)

    插入的列值必须包含在分区值列表中,否则报错

    注 :分区甚至可以按照表达式的返回值,计算所属区.

    但用表达式,不如直接用值来得快. 根据情况而定.

    比如,用 partition by range (year(regtime)) 可以按注册年份来分区.

    hash分区

           基于给定的分区个数,把数据分配到不同的分区。确保数据在预先确定个数的分区中尽可能平均分配。使用partition by hash (expr) partitions num子句对分区类型、分区键和分区个数进行定义。Expr是某列值或一个基于某列值返回一个整数值的表达式,num是一个非负的整数,表示分割成分区的数量,默认为1.

    create table emp_hash(

         uid int auto_increment primary key,

         uname varchar(30),

         age int

     )engine myisam charset=utf8

    partition by hash(uid) partitions 6;

     

    支持两种hash分区,常规hash分区和线性hash分区;

    常规hash:使用的是取模算法

           例如:有4个分区,插入一个uid=234的记录到表中,MOD( 234, 6)=2,则记录会被保存在第二个分区;

           但有个弊端,如果新增一个分区后,会重新计算重新分区,带来性能上的高消耗

    线性hash:线性的2的幂的运算法则

           语法: PATITION  BY  LINEAR  HASH exp PARTITIONS  num;

           声明: num = 4  column_list = 234

      1、先找到下一个大于等于 num 2 的幂,设为V

    V = Power ( 2, Ceilling ( Log ( 2, num ) ) ) = 4

           2、其次,设置 N=F( column_list ) & ( V -1 ) = 234 & (4 -1) = 2

        3、 N >= num 设置 V= CeilingV/2),设置 N = N &V-1

       综上:对于 uid =234N =2 < 4 ,保存在第二个分区

            在分区维护(增加、删除、合并、拆分分区)时,处理的更加迅速;但对比常规hash,各数据之间的分布不太均衡。

     

    key分区

           类似于hash分区,在处理大数据记录时,能够有效地分散热点。支持除BLOB or Text类型外其他类型的列作为分区键,Partition by key(exp)子句来创建一个key分区表,expr是零个或者多个字段名名的列表。与hash分区不同,创建key分区表的时候,可以不指定分区键,默认会首先选择使用主键作为分区键,没有主键的情况,会选择非空唯一键为分区键。也支持LINEAR 关键字。

    三、子分区

    分区表中对每个分区的再次分割,又称为复合分区。

    用于保存非常大量的数据记录。

    四、分区管理

      1.Range & List分区:

      Alter table drop partition 分区名; #删除一个分区。

      Alter table add partition (子句); #增加一个分区

      比如:Alter table add partition (partition p7 values less than(xxx));

      Alter   table reorganize partition  p0[,p1,p2…]  into ( 子句 )  #重新定义分区

      2.Hash & KEY分区

      Alter table coalesce partition num; # 不能删,只能合并hash分区或key分区,也不能通过这个命令增加

      Alter table add partition partitions num; #增加num个分区

     

  • 相关阅读:
    windows编程:第一个windows程序
    百度地图API多个点聚合时,标注添加的标签label地图刷新就丢失的问题解决
    在WPF的WebBrowser控件中屏蔽脚本错误的提示
    使用SQL语句逐条更新每条记录
    通过 HDU 2048 来初步理解动态规划
    一个乱码问题
    2、设置配置文件
    1、搭建 maven 环境
    MyBatis 缓存机制
    关于 Mybatis 设置懒加载无效的问题
  • 原文地址:https://www.cnblogs.com/cshaptx4869/p/10482167.html
Copyright © 2011-2022 走看看