之前一篇文章已经谈到了数据库集群之主从集群也就是读写分离,也提到了读写分离其实只是分担了访问的压力,但是存储的压力没有解决。

存储的压力说白了就是随着系统的演化,需求的增加,可能表的数量会逐渐增多,比如一段时间上个新功能就得加个表。并且随着用户量的增多类似用户表的行数肯定会增多,订单表的数据肯定会随着时间而增多,当这种数据量达到千万甚至上亿的时候,读写分离就已经满足不了,读写性能下降严重。

也就是一台服务器的资源例如CPU、内存、IO、磁盘等是有限的,所以这时候分库分表就上啦!

分库

分库讲白了就是比如现在你有一个数据库服务器,数据库中有两张表分别是用户表和订单表。如果要分库的话现在你需要买两台机子,搞两个数据库分别放在两台机子上,并且一个数据库放用户表,一个数据库放订单表

这样存储压力就分担到两个服务器上了,但是会带来新的问题,所以东西变复杂了都会有新的问题产生。

1、联表查询问题 也就是join了,之前在一个数据库里面可以用上join用一条sql语句就可以联表查询得到想要的结果,但是现在分为多个数据库了,所以join用不上了。就比如现在要查注册时间在2019年之后用户的订单信息,你就需要先去数据库A中用户表查询注册在2019年之后的信息,然后得到用户id,再拿这些id去数据库B订单表中查找订单信息,然后再拼接这些信息返回。所以等于得多写一些代码了。

2、事务问题 搞数据库基本上都离不开事务,但是现在不同的数据库事务就不是以前那个简单的本地事务了,而是分布式事务了,而引入分布式事务也提高了系统的复杂性,并且有些效率不高还会影响性能例如Mysql XA。还有基于消息中间件实现分布式事务的等等这里不展开讲述。

分表

我们已经做了分库了,但是现在情况是我们的表里面的数据太多了,就一不小心你的公司的产品火了,像抖音这种,所有用户如果就存在一张表里吃不消,所以这时候得分表。分别又分垂直分表和水平分表。

垂直分表

垂直分表的意思形象点就像坐标轴的y轴,把x轴切成了两半,对应到我们的表就是比如我们表有10列,现在一刀切下去,分成了两张表,其中一张表3列,另一张表7列。

这个一刀切下去让两个表分别有几列不是固定的,垂直分表适合表中存在不常用并且占用了大量空间的表拆分出去。

就拿头条的用户信息,比如用户表只有用户id、昵称、手机号、个人简介这4个字段。但是手机号和个人简介这种信息就属于不太常用的,占用的空间也不小,个人简介有些人写了一坨。所以就把手机号和个人简介这两列拆分出去。

那垂直分表影响就是之前只要一个查询的,现在需要两次查询才能拿到分表之前的完整用户表信息。

水平分表

水平分表的意思形象点就像坐标轴的x轴,把y轴切成了两半(当然不仅限于切一刀,可以切好几份)。也拿用户表来说比如现在用户表有5000万行数据,我们切5刀,分成5个表,每个表1000万行数据。

水平分表就适合用户表行数很多的情况下,一般单表行数超过5000万就得分表,如果单表的数据比较复杂那可能2000万甚至1000万就得分了,这个得看实际情况有些表很简单可能一亿行都不用分。所以当一个表行数超过千万级别的时候关注一下,如果没有性能问题就可以再等等看,不要急着分表,因为分表会是带来很多问题。

水平分表的问题比垂直分表就更烦了。

要考虑怎么切,讲的高级点就叫路由

1、按id也就是范围路由,比如id 值1999万的放一张表,1000万1999放一张表,一次类推。这个得试的,因为范围分的大了,可能性能还有问题,范围分的小了。。那表不得多死。

这种分法的好处就是容易切啊,简单粗暴,以后新增的数据分表都不会影响到之前的数据,之前的数据都不需要移动。

2、哈希路由 就是取几列哈希一下看看数据哪个库,比如拿id来做哈希,1500取余8等于4,所以这条记录就放在user_4这个表中,2011取余8等于3,所以这条记录就放在user_3中。这种分法好处就是分的很均匀,基本上每个表的数据都差不多,但是以后新增数据又得分表了咋办,以前的数据都得动,比较烦!

3、搞一张表来存储路由关系 还是拿用户表来说,就是弄一个路由表,里面存userId和表编号,表示这个userId是这张user表的的。这种方式也简单,之后又要分表了之后改改路由表,迁移一部分数据。但是这种方法导致每次查询都得查两次,并且如果路由表太大了,那路由表又成为瓶颈了!

再说说查询时候的问题。

比如你要查注册时间最早的前100名用户,这就等于你得在水平分的每一张表都order by 一下注册时间并且取100个,然后再把每个表的100个结果对比一下得到最终的结果。首先操作变麻烦了,以前一个order by就搞定的事情现在变的复杂了,而且还得考虑一个因素就是时间的问题,如果你拆成了20个表,那你得执行20个order by,如果是串行执行的话,这个时间开销也是个问题!

分库分表的实现

具体实现也分为程序代码封装、数据库中间件封装。实现难度会比读写分离更大,至于两种封装的比较在讲读写分离时候已经说了,这里不再赘述。

总结

说了这么多好像分库分表一点都不好啊,没错会引入很多问题,所以在架构设计要遵循演化原则,任何东西都不是一蹴而就的,在不同场景适配不同的架构,架构只有合适的,没有一个架构可以适配任何场景。

在软件中简单够用就是好的,技术没有贵贱,不是用了分布式就牛逼,越复杂的系统维护的成本和难度越高,出现问题的几率越大。这种架构的演化往往都是被用户所驱动的,可以说是"不得已而为之"。

基本上单机数据库可以支撑10万用户量级别。所以一般情况下像数据库吃不消就升级硬件,优化数据库配置、优化代码、引入redis等。只有在真的不行了才上这些更复杂的东西。

面试官:说说Mysql数据库分库分表,并且会有哪些问题?的更多相关文章

  1. php面试专题---mysql数据库分库分表

    php面试专题---mysql数据库分库分表 一.总结 一句话总结: 通过数据切分技术将一个大的MySQLServer切分成多个小的MySQLServer,既攻克了写入性能瓶颈问题,同一时候也再一次提 ...

  2. mysql数据库分库分表shardingjdbc

    分库分表理解 分库分表应用于互联网的两个场景;大量数据和高并发,通常策略有两种:垂直分库,水平拆分 垂直拆分:是根据业务将一个库拆分为多个库,将一个表拆分为多个表,例如:将不常用的字段和经常访问的字段 ...

  3. mysql数据库分库分表(Sharding)

    mysql数据库切分 前言 通过MySQLReplication功能所实现的扩展总是会受到数据库大小的限制.一旦数据库过于庞大,尤其是当写入过于频繁,非常难由一台主机支撑的时候,我们还是会面临到扩展瓶 ...

  4. mysql数据库分库分表(Sharding)(转)

    mysql数据库切分 前言 通过MySQLReplication功能所实现的扩展总是会受到数据库大小的限制.一旦数据库过于庞大,尤其是当写入过于频繁,非常难由一台主机支撑的时候,我们还是会面临到扩展瓶 ...

  5. MyBatis实现Mysql数据库分库分表操作和总结

    前言 作为一个数据库,作为数据库中的一张表,随着用户的增多随着时间的推移,总有一天,数据量会大到一个难以处理的地步.这时仅仅一张表的数据就已经超过了千万,无论是查询还是修改,对于它的操作都会很耗时,这 ...

  6. MySQL+MyCat分库分表 读写分离配置

    一. MySQL+MyCat分库分表 1 MyCat简介 java编写的数据库中间件 Mycat运行环境需要JDK. Mycat是中间件.运行在代码应用和MySQL数据库之间的应用. 前身 : cor ...

  7. Mysql系列四:数据库分库分表基础理论

    一.数据处理分类 1. 海量数据处理,按照使用场景主要分为两种类型: 联机事务处理(OLTP) 面向交易的处理系统,其基本特征是原始数据可以立即传送到计算机中心进行处理,并在很短的时间内给出处理结果. ...

  8. 【转】mysql分库分表,数据库分库分表思路

    原文:https://www.cnblogs.com/butterfly100/p/9034281.html 同类参考:[转]数据库的分库分表基本思想 数据库分库分表思路   一. 数据切分 关系型数 ...

  9. Java实战:教你如何进行数据库分库分表

    摘要:本文通过实际案例,说明如何按日期来对订单数据进行水平分库和分表,实现数据的分布式查询和操作. 本文分享自华为云社区<数据库分库分表Java实战经验总结 丨[绽放吧!数据库]>,作者: ...

随机推荐

  1. Linux war包部署jenkins

    一.介绍Jenkins 1.Jenkins概念 Jenkins是一个功能强大的应用程序,允许持续集成和持续交付项目,无论用的是什么平台.这是一个免费的源代码,可以处理任何类型的构建或持续集成.集成Je ...

  2. css文本省略号

    这里记录下如何用CSS实现单行.多行文本溢出容器的时候用省略号代替溢出部分. 单行文本溢出容器时显示省略号的CSS实现方法 /* 规定当内容溢出元素框(容器)时隐藏 */ overflow: hidd ...

  3. 【linux】dmesg命令显示开机信息和设备加载情况

    Linux命令dmesg用来显示开机信息,kernel会将开机信息存储在ring buffer中.您若是开机时来不及查看信息,可利用dmesg来查看.开机信息亦保存在/var/log目录中,名称为dm ...

  4. 【语义分割】Stacked Hourglass Networks 以及 PyTorch 实现

    Stacked Hourglass Networks(级联漏斗网络) 姿态估计(Pose Estimation)是 CV 领域一个非常重要的方向,而级联漏斗网络的提出就是为了提升姿态估计的效果,但是其 ...

  5. .net core的服务器模式和工作站模式

    来源:济南小老虎 .NET Core是一个开源通用的开发框架,具有跨平台能力,我们在享受其性能飙升的同时,也面临了一些问题.通过观察 NetCore 程序的线上运行情况发现 ,负载高的情况下应用程序占 ...

  6. Redis设置密码,保护数据安全

    1.设置密码方法 在 redis.conf 的配置文件中修改参数 requirepass 的值为需要设置的密码, 保存配置文件后,重启Redis就可以. 建议 设置比较复杂和长的密码,防止被暴力破解. ...

  7. Javase之集合体系(2)之List及其子类ArrayList,LinkedList与Vector及其迭代器知识

    集合体系之List及其子类ArrayList,LinkedList与Vector及其迭代器知识 List(接口) 特点:有序(存储与取出顺序相同),可重复 List子类特点: ​ ArrayList: ...

  8. 漫谈golang设计模式 工厂模式

    工厂模式 意义:创建过程交给专门的工厂子类去完成.定义一个抽象的工厂类,再定义具体的工厂类来生成子类等,它们实现在抽象按钮工厂类中定义的方法.这种抽象化的结果使这种结构可以在不修改具体工厂类的情况下引 ...

  9. JavaScript之找LHS查询和RHS查询

    LHS和RHS,当变量出现在赋值操作的左侧时进行LHS 查询,出现在右侧时进行RHS 查询. LHS 查询是试图找到变量的容器本身,从而可以对其赋值. RHS 理解成retrieve his sour ...

  10. arcgis api 3.x for js 解决 textSymbol 文本换行显示(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...