在大数据量存储的情况下,我们通常都会遇到下面这种情况;

  当mysql中一张表的数据量达到1000万行时,我们的操作系统的性能会大幅度的下降,网站查询的速度回非常的缓慢,而且数据库很可能由于一条小小的sql语句而崩溃,

  面对这种情况,我们可以从物理层面和逻辑层面进行优化,物理层面就是对mysql进行分表,逻辑层面就是sql语句的优化,索引的优化。

  mysql的分表技术大致分为垂直分表,和水平分表,而一般情况下,我们的重点不在垂直分表,而是在水平分表,把一张几千万行的表水平切分为多个小表,从而提高mysql的性能。

  这样做的好处是显而易见的,但是这样也存在着弊端,在逻辑层面,当我们执行sql语句时,或者当使用php操作mysql时进行增删改查时,需要把原有的sql语句里面的表名通通进行改变,比如原来的是select * from user的语句,现在把user表分成10张(user1到user10),我们还需要某种技术来知道你要操作的数据在哪一张表上面,这样就导致了在逻辑层面上的维护成本过高,特别是当我们的数据表要进行再一次扩容时,则要花费更大的人力物力来进行操作。

  而mysql的分区技术则可以有力的避免上述的弊端,既能够将数据在物理层面分割开来,又不需要在逻辑层面,比如php操作mysql的sql语句方面发生改动,从而解决了海量数据存储的问题。

  在mysql5.1以后的版本中,添加了分局技术,分局技术与水平分表类似,但不同的是它是在逻辑层进行的水平分表,但是在应用层,还是一张完整的表,比如我们把user表采用分区技术,分成user1到user10这10张表,这10张表在物理上存在,但我们查询等操作的时候只需要查询user表即可。

  在mysql中,一般有四种分区类型:

  1、RANGE分区技术:把给定区间的值分配给分区。比如user表有100行数据,id从1到100自增长,我们可以采用range技术把user分成3张表:小于30的属于user1表;大于30并且小于60的属于user2表,大于60的属于user3表。

  2、LIST分区技术:类似于range技术,把列里面的固定值分配给每张表,简单来说,就是当某一列的数值为固定的几个值,假如性别就只有男和女,我们就把表分成性别是男的表和是女的表。

  3、HASH分区技术:基于用户给定的某种表达式来对表进行分区,通过表达式对某一列进行计算的返回值来分表,由于每个分区的数据没有规律,所以,一般用来测试mysql分区技术。

  4、KEY分区技术:类似于hash技术,区别在于只计算一列或者多列,且mysql提供哈希函数

  下面列举几个官方手册上的例子来说明这几种技术,

  假定你创建了一个如下的一个表,该表保存有20家音像店的职员记录,这20家音像店的编号从1到20。可以采用range分区技术来实现

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT NOT NULL,
    store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
    PARTITION p0 VALUES LESS THAN (6),
    PARTITION p1 VALUES LESS THAN (11),
    PARTITION p2 VALUES LESS THAN (16),
    PARTITION p3 VALUES LESS THAN (21)
);



partition by range则是说明是采用range分区,上面的代码是根据store_id列来进行分割,less than是说明小于某个值,上面的结果是产生了4张分区,store_id在1-5属于p0,6-10属于p1,11-15属于p2,16-20属于p4,而其它大于20的数据,我们可以在create table 语句中添加一个PARTITION p4 VALUES LESS THAN MAXVALUE来吧其它数据放到p4分区中区。

  接下来再一个例子,假定有20个音像店,分布在4个有经销权的地区,如下表所示:

地区

商店ID 号

北区

3, 5, 6, 9, 17

东区

1, 2, 10, 11, 19, 20

西区

4, 12, 13, 14, 18

中心区

7, 8, 15, 16

要按照属于同一个地区商店的行保存在同一个分区中的方式来分割表,可以使用下面的“CREATE TABLE”语句:


CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY LIST(store_id)
    PARTITION pNorth VALUES IN (3,5,6,9,17),
    PARTITION pEast VALUES IN (1,2,10,11,19,20),
    PARTITION pWest VALUES IN (4,12,13,14,18),
    PARTITION pCentral VALUES IN (7,8,15,16)
);



把商店按照地区来分区,而且每个商店所属的地区已经确定,这样就可以采用LIST分区技术

  下面介绍下HASH分区,HASH分区主要用来确保数据在预先确定数目的分区中平均分布,例如,下面的语句创建了一个使用基于“store_id”列进行 哈希处理的表,该表被分成了4个分区:

CREATE TABLE employees (
    id INT NOT NULL,
    fname VARCHAR(30),
    lname VARCHAR(30),
    hired DATE NOT NULL DEFAULT '1970-01-01',
    separated DATE NOT NULL DEFAULT '9999-12-31',
    job_code INT,
    store_id INT
)
PARTITION BY HASH(store_id)
PARTITIONS 4;

  KEY分区技术与HASH分区技术类似,但是他的key值,可以不是整数类型,可以是字符串或者其他类型,而且而KEY分区的 哈希函数是由MySQL 服务器提供,例如可以采用函数MD5()来实现KEY分区,下面一个小例子,通过线性KEY分割一个表

CREATE TABLE tk (
    col1 INT NOT NULL,
    col2 CHAR(5),
    col3 DATE
) 
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;



由于KEY分区技术使用情况不多,下面值简单的举一个例子,有兴趣的可以去官方手册上去了解更多

  四种分区技术就介绍到这里