一些企业内部系统,用户数量和业务规模有限,因此并不会产生巨大的数据量,这时数据库的存储和读写性能均不会成为瓶颈,没有扩容的需要,因此无须考虑伸缩性。对于一些互联网系统,前后端应用可以通过CDN
、缓存、负载、水平扩展等技术解决瓶颈问题,但是数据库成为最终的读写集中点, 每天都在产生海量的数据和读写请求,因此成为系统瓶颈。
Redis
、
MongoDB
等
NoSQL
数据库虽然支持数据分片,但是并不能取代关系型数据库,对于逻辑关系紧密、复杂的系统,必须借助关系型数据库良好的事务特性来支持。绝大多数公司依然主要采用关系型数据库,而将其他数据库作为辅助。
对于
MySQL
数据库,虽然理论上单表可以支撑上亿条数据,但是性能较差,增加索引、优化SQL
语句已经于事无补。阿里巴巴规约提出 单表行数超过500
万行或单表容量超过
2GB
,才推荐进行分库分表。这个建议的目的是避免过度设计。
数据库的扩容主要采用分库分表的策略,按照垂直拆分和水平拆分两个维度,可分为4
种策略,分别是垂直分表、垂直分库、水平分表和水平分库
1.垂直分表
在一个数据库内,将一个表垂直拆分为多个关联表,表的结构彼此不相同。比如有一个商品表,里面包含商品基本信息,商品广告信息,商品促销信息,但是有的字段频繁访问多,有的则比较少几乎不访问,比如商品促销一年促销几次,此时就可以做垂直分表,将商品表垂直拆分为商品基本信息,商品广告信息,商品促销信息三个表,三个表之间通过相同的商品ID做关联,每个表只包含商品信息的部分字段。
这样就减少了每个表的字段数量,同时尽量将经常访问的字段放在同一个表中,不经常访问的字段放在其他表中,提高数据的检索速度。垂直分表对程序设计有影响,需要同步调整程序。
2.垂直分库
垂直分库是一个数据库拆分为多个数据库,企业早期将所有业务表都放在一个数据库中,包含用户、订单、 产品等所有数据。各个服务都连接到同一个库,从而造成数据库的存储、连接数、读写性能都成为系统瓶颈。
垂直分库就是将一系列相关的表单独拆分为一个数据库,达到专库专用的目的,可以提升数据库的读写性能、连接数。
虽然垂直分表、垂直分库有诸多好处,但是依然没有解决单表数据量过大的问题,每个表中还是存储全量数据。例如,一个订单表有
一千万条数据,垂直拆分为多个表或多个库后,单表依然是一千万条数据。
3.水平分表
水平分表的特点是在同一个数据库内,将一个表水平拆分为多个表,表结构均相同。当单表记录数过大时可以进行水平拆分。
4.水平分库
水平分库的特点是将同一个表水平拆分到多个数据库中,每个表的结构相同。 水平分库与水平分表的原理基本相同,即将一个表拆分为多个相 同结构的表,分散在不同的数据库中。
水平分库也面临着诸多问题:如何进行跨库关联查询?如何进行跨库的分页和排序?如何保证数据事务的一致性?如何进行数据迁移?分库分表的基本原则有以下3
点。
(
1
)不进行过度设计,不需要将所有库、所有表都进行分库分表。分库分表虽然有诸多好处,很好地解决了数据库的存储容量和性能瓶颈,但是程序复杂度会急剧升高,出现问题的概率呈指数级增长。
(
2
)不在项目初期就进行分库分表,而是动态调整。当单表数据量增长到一定程度时再进行分库分表即可。
(
3
)先垂直拆分,再水平拆分。如果垂直拆分能够解决问题,则不需要再进行水平拆分。