为什么要分库分表

https://blog.csdn.net/liu1pan2min3/article/details/83868092

1.为什么要分库分表

       1)随着业务的不断增长,数据库中表越来越多,同时表中的数据量也越来越大,业务总量达长到一定程度以后,数据库进行增删改查的开销就会显著增加,并且数据库的承载能力毕竟是有限的(受限于CPU,磁盘,内存,IO等)。

       2)主流数据库性能已经很优,采用升级服务器(小型机)也能解决性能和存储问题,为什么不采用?

             综合考虑成本的原因,小型机动辄几百万,大型机甚至上千万,对于普通公司来说成本未免太高,而既然能够通过分库分表就能解决的问题,何乐而不为。

       3)数据库Replication主从同步机制不也能解决读写吞吐和性能问题, 为什么不采用?

             对于热点数据,采用Replication机制的确可以解决很多问题,但是它也存在自身的缺陷,首先它依赖于读操作的比例(读操作越高性能越好),Master往往成为瓶颈所在,因为写操作需要顺序排队来执行,过载的话Master首先抗不住,其次Slaves的数据同步的延迟也可能比较大,write操作在Master上执行以后还需要在每台slave机器上跑一次。

         这块原因可以从业务发展史进行说明。

            

2.分库分表的优缺点

分库分表的优点?

      优点:提高应用的性能,缓解同一个库和同一张表的压力,减轻单台主机的负载压力 。实现业务的线性可控,通过横向扩展增加数据库的方式,实现业务的线性增长。

      缺点:  需要投入人力、物力进行开发与维护。

四种实现方式:

      分库不分表,不分库分表,分库分表以及不分库不分表(退化)。

分库不分表(垂直切分)   

       也可以理解为, 数据库表中大字段拆离问题。

优点:

      1)实现简单,只需将不同业务模块所用的表拆到不同数据库。(客服模块,商服模块,下单模块,核销和结算模块, 退款模块)。

      2)库与库之间界限分明,便于维护。

 缺点:

       1)不利于频繁跨库操作(比如:同时操作两个库)。

       2)未解决单表数据量大的问题。

 不分库分表(水平切分)

  优点:

       1)  实现较简单,仅在表级别进行拆分,不需要考虑多数据源等问题。

       2)  写入性能得到一定程度的提高,由原来写入一张大表,改为写入一张小表。

   缺点:

       1)未解决单库数据量大的问题   。

 分库分表(混合切分)

  优点:

        1)可扩展性好,各方面性能都得到提高。

   缺点:

        1)实现复杂,面临更多数据拆分以及迁移。

不分库不分表(不切分)

   优点:

        1)实现简单。

   缺点:

        1)不能支撑业务长期发展。

3.分库分表带来的问题

多数据源问题

     原本只需要查询一次库一个表,现在需要查多个库中多张表。 例如深度分页问题?  (其实不属于主要问题, 在设计分库分表时候就要杜绝出现这样问题)

     简单举一个例子,假设在订单列表中,一个分页中有100条数据,我们现在要求查询出第一页数据,如何查询?分两种情形考虑,单个数据库中以及多数据库中。

         在单数据库中,我们需要查询最近的100个订单信息,一条降序排列的sql语句就OK。

查询最近100条订单信息 折叠原码

1

2

//单数据库中 DB 

select * from mtp_order  order by  gmt_created  desc   limit  0100 G;              // so  easy !

         如果有两个数据库中, 则需要在两个数据库中分别执行这条sql语句,  分别查询出前100条数据。 然后在内存中降序排序,即可选择出前100条订单信息。 看起来也比较简单啊。  

两个数据库分别查询前100条数据库 展开原码

         如果要查询第二页的数据哪? 即按时间降序排序101-200的订单信息。也分两种情况来说。单数据库中:

单数据库中查询第二页数据 展开原码

两个数据库中: 

查询第二页数据 展开原码

      两个数据库各选择出前200条数据,总共400条数据,按照降序排序, 选择出100 - 199的订单数据为第二页的数据。数据加倍了,不是分别选择 100 -199 的数据进行合并然后排序 ,这种方式是错误的。

      理解的关键就是全局排序,局部排序无意义。 

路由问题

      根据userid或者orderId如何路由到具体的库和表。(数据平均和负载均衡问题,主要从业务场景出发进行考虑,比如核销可能不需要考虑负载均衡(老数据定期进行归档), 用户订单数据就一定要考虑负载均衡和数据均分)

事务问题

       同一个事务,可能要操作不同数据库的不同表,如何保证事务的特性。 多数据源保证事务,一般可采用方案两种,分布式事务和应用程序和数据库共同控制。

分布式事务

优点:

       1)直接交由数据库进行管理,实现简单。

缺点:

        1)性能代价太高。

应用程序和数据库共同控制

         将一个跨多个数据库的分布式事务分拆成多个仅处于单个数据库上面的小事务,比通过应用程序来总控各个小事务。

优点:

         1)性能高。

缺点:

         1)改动或实现起来复杂。

跨节点join的问题

      无法join位于不同库中的表。  (最需要考虑问题)

跨节点order by、group by的问题

       需要基于全部数据集合进行计算,但是无法order by或group by 不同库中的多张表。

跨节点count、sum等聚合函数的问题

       同样需要基于全部数据集合进行计算。  

额外的数据管理与计算能力

       例如:深度分页问题,需要对取到的数据重新在内存中进行排序。    

老数据迁移问题

       原有数据迁移到对应的新库新表中。

回归测试问题

  

         

             

原文地址:https://www.cnblogs.com/sunny3158/p/14395162.html