问题
移动互联网时代,海量的用户每天产生海量的数据量,MySQL单表容量在1KW以下是最佳状态, 一张表无法搞定
另外,一台服务器的资源(CPU、磁盘、内存、IO等)是有限的,最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈,。
方案
目前比较普遍的方案有3个:
- 读写分离
- 分库分表
- 垂直切分
- 水平切分
- NoSQL/NewSQL
分区
就是把一张表的数据分成N多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上,但不能分配到不同服务器上
本质 : 分区只是一张表中的数据的存储位置发生改变
一张大表进行分区后,他还是一张表,不会变成二张表,但是他存放数据的区块变多
作用
主要可以提升查询效率
优点
- 相对于单个文件系统或是硬盘,分区可以存储更多的数据;
- 数据管理比较方便,比如要清理或废弃某年的数据,就可以直接删除该日期的分区数据即可;
- 精准定位分区查询数据,不需要全表扫描查询,大大提高数据检索效率;
- 可跨多个分区磁盘查询,来提高查询的吞吐量;
- 在涉及聚合函数查询时,可以很容易进行数据的合并;
分表
原理: 就是把一张表分成N多个小表
分表能够解决 单表数据量过大带来的查询效率下降的问题
拆分后表的数量一般为 2的n次方
- 例
订单表order,由于order表记录条数太多,根据user_id 取模分库 拆分成256张表:order_1,order_2,order_3…
select * from order_${no} where id = '#{id}';
select * from order_1 where user_id='257';
select * from order_2 where user_id='258';
作用
分表后,单表的并发能力提高了,磁盘I/O性能也提高了,写操作效率提高了
缺点
分表无法给数据库的并发处理能力带来质的提升。
面对高并发的读写访问,当数据库master服务器无法承载写操作压力时,不管如何扩展slave服务器都没有意义
如果你的单机性能很低了,这时候就需要分库
分库
原理: 把原本存储于一个库的数据分块存储到多个库上
主要目的 是为突破单节点数据库服务器的 I/O 能力限制,解决数据库扩展性问题。
数据库进行拆分,从而提高数据库高并发写入能力,这就是所谓的分库
分库分表存在的问题
事务问题, 分库分表,就变成了分布式事务
跨库跨表的join问题, 跨表的问题
额外的数据管理负担和数据运算压力
使用场景
什么时候考虑使用分区?
- 当访问量不大,但表数据比较多时,可以只进行分区
- 一张表的查询速度已经慢到影响使用的时候。sql经过优化,数据量大
- 表中的数据是分段的
- 对数据的操作往往只涉及一部分数据,而不是所有的数据
什么时候考虑分表?
- 当访问量大,且表数据比较大时,分区分表可以互相配合使用。
- 一张表的查询速度已经慢到影响使用的时候。sql经过优化,数据量大
- 当频繁插入或者联合查询时,速度变慢
什么时候考虑使用分库?
- 单台DB的存储空间不够
- 随着查询量的增加单台数据库服务器已经没办法支撑
总的来说,优先考虑分区。当分区不能满足需求时,开始考虑分表,合理的分表对效率的提升会优于分区。