MySql 分库分表:垂直分表、垂直分库、水平分表、水平分库

读写分离解决的是数据库读写操作的压力,但是没有分散数据库的存储压力,利用分库分表可以解决数据库的储存瓶颈,并提升数据库的查询效率。

二、垂直拆分:

(1)垂直分表:将一个表按照字段分成多个表,每个表存储其中一部分字段。一般会将常用的字段放到一个表中,将不常用的字段放到另一个表中。

优点:

  • (1)避免IO竞争减少锁表的概率。因为大的字段效率更低,第一,大字段占用的空间更大,单页内存储的行数变少,会使得IO操作增多;第二数据量大,需要的读取时间长。
  • (2)可以更好地提升热门数据的查询效率。

(2)垂直分库:按照业务模块的不同,将表拆分到不同的数据库中,适合业务之间的耦合度非常低、业务逻辑清晰的系统。

优点:

  • 降低业务中的耦合,方便对不同的业务进行分级管理
    +可以提升IO、数据库连接数、解决单机硬件存储资源的瓶颈问题

(3)垂直拆分(分库、分表)的缺点:

  • 主键出现冗余,需要管理冗余列
  • 事务的处理变得复杂
  • 仍然存在单表数据量过大的问题

三、水平拆分:

(1)水平分表:在同一个数据库内,把同一个表的数据按照一定规则拆分到多个表中。

优点:

  • 解决了单表数据量过大的问题
  • 避免IO竞争并减少锁表的概率

(2)水平分库:把同一个表的数据按照一定规则拆分到不同的数据库中,不同的数据库可以放到不同的服务器上。

优点:

  • 解决了单库大数据量的瓶颈问题
  • IO冲突减少,锁的竞争减少,某个数据库出现问题不影响其他数据库,提高了系统的稳定性和可用性

(3)水平拆分(分表、分库)的缺点:

  • 分片事务一致性难以解决
  • 跨节点JOIN性能差,逻辑会变得复杂
  • 数据扩展难度大,不易维护

四、分库分表存在的问题的解决:

(1)事务的问题:

① 方案一:使用分布式事务:

  • 优点:由数据库管理,简单有效。
  • 缺点:性能代价高,特别是shard越来越多。

② 方案二:程序与数据库共同控制实现,原理就是将一个跨多个数据库的分布式事务分解成多个仅存在于单一数据库上面的小事务,并交由应用程序来总体控制各个小事务。

  • 优点:性能上有优势;
  • 缺点:需要在应用程序在事务上做灵活控制。如果使用了spring的事务管理,改动起来会面临一定的困难。

(2)跨节点 Join 的问题:

解决该问题的普遍做法是分两次查询实现:在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。

(3)跨节点count,order by,group by,分页和聚合函数问题:

由于这类问题都需要基于全部数据集合进行计算。多数的代理都不会自动处理合并工作,解决方案:与解决跨节点join问题的类似,分别在各个节点上得到结果后在应用程序端进行合并。和 join 不同的是每个结点的查询可以并行执行,因此速度要比单一大表快很多。但如果结果集很大,对应用程序内存的消耗是一个问题。

五、分库分表后,ID键如何处理?

分库分表后不能每个表的ID都是从1开始,所以需要一个全局ID,设置全局ID主要有以下几种方法:

(1)UUID:

  • 优点:本地生成ID,不需要远程调用,全局唯一不重复。
  • 缺点:占用空间大,不适合作为索引。

(2)数据库自增ID:在分库分表表后使用数据库自增ID,需要一个专门用于生成主键的库,每次服务接收到请求,先向这个库中插入一条没有意义的数据,获取一个数据库自增的ID,利用这个ID去分库分表中写数据。

  • 优点:简单易实现。
  • 缺点:在高并发下存在瓶颈。

(3)Redis生成ID:

  • 优点:不依赖数据库,性能比较好。
  • 缺点:引入新的组件会使得系统复杂度增加

(4)Twitter的snowflake算法:是一个64位的long型的ID,其中有1bit是不用的,41bit作为毫秒数,10bit作为工作机器ID,12bit作为序列号。

  • 1bit:第一个bit默认为0,因为二进制中第一个bit为1的话为负数,但是ID不能为负数.
  • 41bit:表示的是时间戳,单位是毫秒。
  • 10bit:记录工作机器ID,其中5个bit表示机房ID,5个bit表示机器ID。
  • 12bit:用来记录同一毫秒内产生的不同ID。

(5)美团的Leaf分布式ID生成系统,美团点评分布式ID生成系统:

猜你喜欢

转载自blog.csdn.net/qq_27870421/article/details/120745207