博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数据库切分“基本思想”、“常见问题”
阅读量:2351 次
发布时间:2019-05-10

本文共 1859 字,大约阅读时间需要 6 分钟。

优点:

分库降低了单点机器的负载;

分表提高了数据操作的效率,尤其是write操作的效率

 

1.垂直切分

适用场景:表多数据多。

特点:规则简单、业务逻辑清晰、业务耦合度非常低。根据相同业务使用的表放到相同的数据库。在垂直切分出的表聚集内,找出“根元素”,按“根元素”进行水平切分,也就是从“根元素”开始,把所有和它直接与间接关联的数据放入一个shard(碎片)里,如对于社交网站,几乎所有数据最终都会关联到某个用户上,基于用户进行切分就是最好的选择。再比如论坛系统,用户和论坛两个模块应该在垂直切分时被分在了两个shard里,对于论坛模块来说,Forum(论坛)显然是聚合根,因此按Forum进行水平切分,把Forum里所有的帖子和回帖都随Forum放在一个shard里是很自然的。

 

 

2.水平切分

适用场景:表少数据多。

特点:拆分规则复杂、后期维护复杂,针对数量大的表拆分串联,同一个表中的不同数据拆分到不同的数据库中。

切分优点:索引开销降低,减少单表写操作锁表时间。

如article表中现在有5000w条数据,此时我们需要在这个表中增加(insert)一条新的数据,insert完毕后,其他数据库 会针对这张表重新建立索引,5000w行数据建立索引的系统开发开销还是不容忽视的。但是反过来,假如我们将这个表分成100个table呢,从article_001一直到article_100,5000w行数据平均下来,每个子表里边就只有50万行数据,这时候我们向一张只有50w行数据的table中insert数据后建立索引的时间就会呈数量级的下降,极大了提高了db的运行时效率,提高了db的并发量。

切分规则:

a.按号段分

eg:id为区分,1~1000的对应db1,1001~2000的对应db2,2001~2100的对应db3,以此类推

id为区分,1~1000的对应db1,1001~2000的对应db2,以此类推

优点:可部分迁移

缺点:数据分布不均

 

b.hash取模分

对id进行hash(或者如果id是数值型的话直接使用id的值也可),然后用一个特定的数字,比如应用开发中需要将一个其他数据库 切分成4个其他数据库 的话,我们就用4这个数字对id的hash值进行取模运算,也就是id%4,这样的话每次运算就有四种可能:结果为1的时候对应db1;结果为2的时候对应db2;结果为3的时候对应db3;结果为0的时候对应db4,这样一来就非常均匀的将数据分配到4个db中。

优点:数据分布均匀

缺点:数据迁移的时候麻烦,不能按照机器性能分摊数据

 

c.在认证库中保存其他数据库配置

就是建立一个db,这个db单独保存user_id到db的映射关系,每次访问其他数据库 的时候都要先查询一次这个其他数据库 ,以得到具体的db信息,然后才能进行我们需要的查询操作。

优点:灵活性强,一对一关系

缺点:每次查询之前都要多一次查询,性能大打折扣

 

通常系统水平切分和垂直切分联合使用,系统做垂直切分,个别大表水平切分,即先垂直切后水平切。

 

3.切分的常见问题和应对策略

a.事务问题:

解决事务问题目前有两种可行的方案:分布式事务和通过应用程序与数据库共同控制实现事务下面对两套方案进行一个简单的对比。

方案一:使用分布式事务

   优点:交由数据库管理,简单有效

   缺点:性能代价高,特别是shard越来越多时

方案二:由应用程序和数据库共同控制

    原理:将一个跨多个数据库的分布式事务分拆成多个仅处

          于单个数据库上面的小事务,并通过应用程序来总控

          各个小事务。

    优点:性能上有优势

    缺点:需要应用程序在事务控制上做灵活设计。如果使用   

          了spring的事务管理,改动起来会面临一定的困难。

b.跨节点Join的问题

   只要是时行切分,跨节点Join的问明是不可避免的。但是良好的设计和切分却可以减少此类情况的发生。解决这一问题的普遍做法是分两次查询实现。在第一次查询的结果集中找出关联数据的id,根据这些id发起第二次请求得到关联数据。

c.跨节点的count,order by,group by以及聚合函数问题

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

 

转载地址:http://ahevb.baihongyu.com/

你可能感兴趣的文章
SpringCloud 2.x学习笔记:3、Hystrix(Greenwich版本)
查看>>
SpringCloud 2.x学习笔记:4、Zuul(Greenwich版本)
查看>>
ajax提交JSON数组及Springboot接收转换为list类
查看>>
SpringCloud 2.x学习笔记:5、Config(Greenwich版本)
查看>>
RabbitMQ安装、配置与入门
查看>>
Java异常
查看>>
Ibatis代码自动生成工具
查看>>
ant build.xml教程详解
查看>>
彻底理解ThreadLocal
查看>>
localhost与127.0.0.1的区别
查看>>
windows下的host文件在哪里,有什么作用?
查看>>
操作系统之字符集
查看>>
OSI和TCP/IP
查看>>
Redis集群搭建最佳实践
查看>>
ZooKeeper原理及使用
查看>>
Zookeeper集群搭建
查看>>
利用TypePerf.exe查看性能
查看>>
分布式框架Dubbo
查看>>
解决PKIX:unable to find valid certification path to requested target 的问题
查看>>
hibernate.cfg.xml配置详解
查看>>