数据库|面试官:说说MySQL数据库分库分表,并且会有哪些问题?


分库讲白了就是比如现在你有一个数据库服务器 , 数据库中有两张表分别是用户表和订单表 。 如果要分库的话现在你需要买两台机子 , 搞两个数据库分别放在两台机子上 , 并且一个数据库放用户表 , 一个数据库放订单表
数据库|面试官:说说MySQL数据库分库分表,并且会有哪些问题?
本文插图

这样存储压力就分担到两个服务器上了 , 但是会带来新的问题 , 所以东西变复杂了都会有新的问题产生 。
1、联表查询问题 也就是join了 , 之前在一个数据库里面可以用上join用一条sql语句就可以联表查询得到想要的结果 , 但是现在分为多个数据库了 , 所以join用不上了 。 就比如现在要查注册时间在2019年之后用户的订单信息 , 你就需要先去数据库A中用户表查询注册在2019年之后的信息 , 然后得到用户id,再拿这些id去数据库B订单表中查找订单信息 , 然后再拼接这些信息返回 。 所以等于得多写一些代码了 。
2、事务问题 搞数据库基本上都离不开事务 , 但是现在不同的数据库事务就不是以前那个简单的本地事务了 , 而是分布式事务了 , 而引入分布式事务也提高了系统的复杂性 , 并且有些效率不高还会影响性能例如Mysql XA 。 还有基于消息中间件实现分布式事务的等等这里不展开讲述 。
分表

我们已经做了分库了 , 但是现在情况是我们的表里面的数据太多了 , 就一不小心你的公司的产品火了 , 像抖音这种 , 所有用户如果就存在一张表里吃不消 , 所以这时候得分表 。 分别又分垂直分表和水平分表 。
垂直分表
垂直分表的意思形象点就像坐标轴的y轴 , 把x轴切成了两半 , 对应到我们的表就是比如我们表有10列 , 现在一刀切下去 , 分成了两张表 , 其中一张表3列 , 另一张表7列 。
这个一刀切下去让两个表分别有几列不是固定的 , 垂直分表适合表中存在不常用并且占用了大量空间的表拆分出去 。
就拿头条的用户信息 , 比如用户表只有用户id、昵称、手机号、个人简介这4个字段 。 但是手机号和个人简介这种信息就属于不太常用的 , 占用的空间也不小 , 个人简介有些人写了一坨 。 所以就把手机号和个人简介这两列拆分出去 。
【数据库|面试官:说说MySQL数据库分库分表,并且会有哪些问题?】那垂直分表影响就是之前只要一个查询的 , 现在需要两次查询才能拿到分表之前的完整用户表信息 。
水平分表
水平分表的意思形象点就像坐标轴的x轴 , 把y轴切成了两半(当然不仅限于切一刀 , 可以切好几份) 。 也拿用户表来说比如现在用户表有5000万行数据 , 我们切5刀 , 分成5个表 , 每个表1000万行数据 。

水平分表就适合用户表行数很多的情况下 , 一般单表行数超过5000万就得分表 , 如果单表的数据比较复杂那可能2000万甚至1000万就得分了 , 这个得看实际情况有些表很简单可能一亿行都不用分 。 所以当一个表行数超过千万级别的时候关注一下 , 如果没有性能问题就可以再等等看 , 不要急着分表 , 因为分表会是带来很多问题 。
水平分表的问题比垂直分表就更烦了 。
要考虑怎么切 , 讲的高级点就叫路由
1、按id也就是范围路由 , 比如id 值1~999万的放一张表 , 1000万~1999放一张表 , 一次类推 。 这个得试的 , 因为范围分的大了 , 可能性能还有问题 , 范围分的小了 。。 那表不得多死 。
这种分法的好处就是容易切啊 , 简单粗暴 , 以后新增的数据分表都不会影响到之前的数据 , 之前的数据都不需要移动 。
2、哈希路由 就是取几列哈希一下看看数据哪个库 , 比如拿id来做哈希 , 1500取余8等于4 , 所以这条记录就放在user_4这个表中 , 2011取余8等于3 , 所以这条记录就放在user_3中 。 这种分法好处就是分的很均匀 , 基本上每个表的数据都差不多 , 但是以后新增数据又得分表了咋办 , 以前的数据都得动 , 比较烦!


推荐阅读