以下博文参考:https://blog.csdn.net/weixin_44062339/article/details/100491744
1.什么是分库分表,为什么要做分库分表
随着业务的快速发展,数据库中的数据量猛增,访问性能变慢,优化迫在眉睫。
分析:关系型数据库本身比较容易成为系统瓶颈,包括单机存储容量,连接数,处理能力都有限。
尤其是当单表的数据量达到1000W或者100G以后,由于查询维度比较多,即使添加从库、优化索引,做很多操作时性能仍旧下降严重。
因此为提高服务性能,需要进行进一步的操作,于是有以下方案:
方案1:通过提升服务器硬件能力来提高数据处理能力,比如增加存储容量,cpu等,但是这种方案成本很高,而且如果瓶颈在mysql本身时,
那么提高硬件也是有限的
方案2:
把数据分散在不同的数据库中,使得单一的数据库的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的
如以下分库:
总结:
分库分表就是为了解决由于数据量较大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数组库组成,将数据大表拆分成若干数据表组成,
使得单一的数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。
2.如何做分库分表
下面我们来讲讲如何做分库分表,分库分表包括分库和分表两个方面,通常包括垂直分库,水平分库,垂直分表,水平分表四种方式。
2.1.垂直分表
存在这样的场景:我们在访问某宝的时候,想要去买一箱椰汁奶,这个时候,我们在商品列表搜索到的都是关于【椰汁奶】商品的价格信息以及图片信息等,
这些属于高频访问字段,当我们看中了一款椰汁奶时,我们点击到商品详情查看,这些商品详情,包括商品的描述等,访问频率较低,且占据的存储空间较大
垂直分表就是将一个表按照字段分成多表,每个表存储一部分字段。对于上面我们所讲的例子来说,即是将商品价格,图片等信息放在一张表中,将商品描述以及
具体的信息等放在另外一种表中。
垂直分表优点:
1.如果未将商品信息与商品详情分隔开,那么访问商品详情和商品信息时,存在IO争抢,
如果将商品详情与商品信息分表存储,则能够避免ID争抢,且较少锁表的几率,查看详情的用户与商品信息的浏览互不影响
2.将商品详情与商品信息(热门数据)分表存储时,充分发挥了热门数据的操作效率,且商品信息的操作效率不会被商品描述的低效率所拖累
小tips:为什么大字段IO效率低:
a.由于数据量本身大,读取时需要更长的时间
b.数据量大时,数据库中数据存储时,页是数据存储单位,很多查找和定位操作都是以页为单位,而单页内数据行越多数据整体性能越好。
而大字段存储时,占用空间大,单页内存储行数少,查找或者访问数据时,存在跨页查询现象,因此IO效率较低
c.数据库加载数据时是以行为单位将数据加载到内存中,这样表中字段长度短且访问效率高,内存才能加载更多的数据,命中率更高,减少了
磁盘IO,而大字段数据加载时,由于字段长度较长访问效率较低,也间接造成了命中率低,增加了磁盘IO,降低了数据库的性能
通常垂直拆分的原因如下:
a.把不常用的字段单独放在一张表中
b.将text,blob等大字段拆分出来放在附表中
c.经常组合查询的列放在同一张表中
2.2垂直分库
上述经过垂直分表,数据库的访问性能得到一定的提升,但是还没有达到要求,因为所有的数据始终还是在一台服务器中,库内垂直分表
只解决了单一表数据量过大的问题,但没有将表分布在不同的服务器上,因为每个表还是竞争到同一个物理机的cpu,内存,网络,io,磁盘等
对于上述的描述的买【椰汁奶】的过程,我们将【买家库】和【卖家库】分开,并把这两个库分散到不同的服务器上,如下图:
为什么会这样分呢,因为商品信息和商品描述业务耦合度较高,因为一起被放在商品库;而由于店铺信息相对独立,因此单独被放在一个库中
总结如下:
垂直分库是按照业务划分表,分别将耦合度较低的表与常用表分布在不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用
垂直分库带来了哪些提升:
1.解决了业务的耦合,业务清晰:因为按照业务将表分类
2.能对不同的业务的数据进行分局管理、维护、监控、扩展等:按照业务进行划分后,可分别对不同的业务进行维护
3.高并发场景下,垂直分库一定程度的提升了IO、数据库连接数、降低单机硬件资源的瓶颈。
垂直分库是通过将表按照业务进行分类,然后分布在不同的数据库上,并且可以将这些数据库部署在不同的服务器上,从而达到多个服务器共同分摊压力的效果
但是依然没有解决单表数据量过大的问题。
2.3水平分库
当上述的商品库随着业务量的增长,单库存储的数据量超出预估,单台服务器无法支撑,这个时候,应该怎么办呢,如果尝试再次垂直分库,但是目前已经从业务
的角度进行分库了,无法再细分业务了,这个时候只有尝试水平分库,怎么进行水平分库呢
将店铺ID为单数和店铺ID为双数的信息分别放在两个库中,即要操作某条数据时,要先分析店铺信息ID是单数还是双数,进行判断,如果为店铺ID为单数则将此操作映射到A库,
如果店铺ID为双数,则将此操作映射到B库
总结:水平分库是把同一个表中的数据,按照某种特性(一定规则)拆分到不同的数据库中,每个库可以放在不同的服务器中
水平分库后带来了什么(提升)
a.首先解决了单表数据量过大的问题,解决了高并发而导致的性能瓶颈
b.提高了性能的稳定性以及可用性
小tips:
稳定性体现在,IO冲突减少,锁表减少,可用性指某个库出问题时,部分仍旧可用
适用场景:当一个应用很难再以垂直粒度进行切分时,或者垂直切分后,数据量行数巨大,存在单库读写、存储性能瓶颈时,这个时候就需要水平分库了
经过水平切分的优化时,往往能解决单库存储量以及性能瓶颈的问题。但是由于同一个表被分配在不同的数据库中,因此需要进行额外数据操作的路由操作,因为大大提升了系统复杂度
2.4水平分表
水平分表也是将表进行水平拆分,其目的也是解决单表数据量较大的问题。与水平分库的思路类似,不过这次操作的目标是表,商品信息以及商品描述被分成了
两套表,如果商品ID为双数,则将此操作映射只A表,如果商品ID为单数,则将此操作映射至商品信息B表
水平分表是在同一个数据库内,把同一个表中的数据按照一定的规则拆分到多个表中
它的作用是什么呢:
a.优化了单一表由于数据量大而产生的性能问题
b.避免ID争抢,减少锁表的几率
库内的水平分表,解决了单一表数据量过大的问题,分出来的小表只包含一部分数据,从而使得单个表的数据量变小,提高检索性能
总结:
垂直分表:将表中的字段按照访问的频次,是否是大字段的原则来拆分为单个表,这样既能使的业务清晰,还能提升部分性能,拆分后,尽量从业务角度避免联查
否则性能方面将得不偿失
垂直分库:将多个表按照业务进行分类,分别存在不同的数据库中,不同的数据库可分布在不同的数据库中,从而减少数据库的访问压力,大大提升性能,
但是它需要解决跨库带来的复杂问题
水平分表:将表的数据(按数据行)分到同一个数据库的多个数据表中,小幅提升了单表的检索性能,它仅仅作为水平分库的一个补充优化
水平分库:把一个表的数据(按数据行)分到不同数据库中,每个库只有这个表的数据数据,这些库可以分布在不同的服务器上,从而使访问压力被多服务器负载,大大提升性能。它不仅需要
解决跨库带来的所有复杂问题,还要解决数据路由的问题。
垂直分库和水平分库区别在于:垂直拆分是将业务进行区分,针对的是整个业务的所有表,是对数据行的拆分,不影响表结构,而水平拆分是针对的单表来拆分,
拆分了表的结构
垂直分表和水平分表:垂直分表是按照一定的频次或者字段大小来进行分表,而水平分表是按照一定的规则进行分表