当一个系统访问量及用户量增加,数据库的数据也随之增加。当Mysql中一张表的记录数超过1000万,会出现性能的大幅下降,甚至一条简单的SQL查询都有可能阻塞整个数据库。这时需要对数据库的架构动态扩展设计如:水平分区,才能使系统达到友好的用户体验。
示例图1
示例图2
水平分区设计思路
水平分区技术:同一个数据库表中的记录通过Hash算法取模方式等拆成多张表,分别存储在不同的数据库相同的表名中。如:原来有1亿条记录,可以用100张表存储,每张表就只存储100万条记录。成为解决海量数据存储的有效方法。
Mysql常用的分区方式:
mysql5.1及以上版本才支持分区。
1、RANGE分区:基于属于一个给定连续区间的列值,把这个区间的列值分配给分区。
如:订单表orderId为1~10000的对应一张表,10001~20000的对应一张表,以此类推。
实现思路:
创建表
create table order ( | |
orderId int auto_increment primary key, | |
orderMoney Double(10,2), | |
orderDate date, | |
shopId int | |
) engine=myisam | |
partition by range(orderId ) ( | |
partition p0 values less than(10000), | |
partition p1 values less than(20000), | |
partition p3 values less than(30000) , | |
...以此类推 | |
) |
注:当添加数据到表里时,如果查询orderId 值小于20000的记录,它只要检索p0和p1分区。这样速度就快。
2、LIST分区:类似于RANGE分区,区别是基于列值匹配一个离散值集合中的某个值来选择。
实现思路:
创建表
create table order ( | |
orderId int auto_increment primary key, | |
orderMoney Double(10,2), | |
orderDate date, | |
shopId int | |
) engine=myisam | |
partition by range(shopId ) ( | |
partition p0 values in(1,3,5), | |
partition p1 values in (2,4,6), | |
...以此类推 | |
) |
注:list 分区只能插入的值放在某个已定匹配的分区里,如果没有那个值对应匹配,就不能插入。
3、HASH分区:基于用户定义表达式的返回值来选择分区,该表达式使用将要插入到表中的这些行的列值进行计算。
实现思路:
创建表
create table order ( | |
orderId int auto_increment primary key, | |
orderMoney Double(10,2), | |
orderDate date, | |
shopId int | |
) engine=myisam | |
partition by hash(orderId) partitions 5 | |
) |
注:分为5个分区,当添加数据时,根据HASH算法进行取模运算。如:取模为1,将数据分配到对应的1区。
4、KEY分区:类似于HASH分区,区别是HASH分区允许用户自定义表达式,而Key分区不允许用户自定义表达式。HASH分区只支持整数分区,而Key分区支持使用BLOB或Text类型外其他类型的列作为分区键。
实现思路:
创建表
create table order ( | |
orderId int auto_increment primary key, | |
orderMoney Double(10,2), | |
orderDate date, | |
shopId int | |
) engine=myisam | |
partition by key(orderId) partitions 5 | |
) |