MySql分库分表解决方案
为什么要进行分库分表
超大容量
性能问题
个别单表数据可能上亿,从而出现IO瓶颈,引起查询效率的问题,所以需要 分表。
使用单个数据库解决所有应用节点的话,数据库所在的服务器的性能瓶颈,也会导致数据性能下降,所以需要 分库。
分表分库,也叫做 数据分片。
如何分表分库
垂直分表
垂直分库
水平分表
垂直分表
拆分列,就是垂直分表,比如商品表可以拆分为商品信息表、商品标签表、商品价格表… 然后通过关联关系维持他们之间的联系。
优点:
解决了当单表列过多时,会造成mysql性能瓶颈的问题
解决单个表中列过多的问题。
垂直分库
根据业务模块划分数据库,比如订单数据库、用户数据库…
优点:
业务拆分、解耦
每个数据库可以部署在不同的服务器上(资源利用率高)
大部分公司都是根据soa的节点去划分
解决了单个库中表数量过多的问题。
水平分表
大数据表拆为小表,当一张表的数据上亿时,IO瓶颈明显,比如订单表可以拆分为多个小的订单表,从而提高查询效率…
mysql官方性能数据:单表的查询瓶颈在500-1000万左右,超过1000万将会出现性能问题。
常见的拆分策略
垂直拆分
垂直拆分需要根据业务来决定拆分情况,最好将有关联的表放入同意库中,避免跨数据库查询。
水平拆分
一致性hash:
根据某个字段的维度,进行拆分,比如,将 t_user
表拆分为10个小表,可以使用 userId%10
进行分库,根据他的只将数据保存在对应的表中。
取模的方式当模发生变化时,就会影响已经拆分的数据,从而要进行数据迁移。
字段的选择将会影响sql实现的难度。
范围切分:
比如,userId在 [0, 100w)之间的数据放入到user1表中。
日期拆分:
比如,将2018年注册的用户放入到 user_2018表中。
拆分的问题
跨库join
解决方案:
服务层调用:rpc先查出user信息,再给order服务使用,注意要提供批量查询接口,不可多次调用服务进行处理
使用全局表,每个应用都可以查询此表,全局表的数据应该比较固定
字段冗余(空间换时间):很多地方都需要进行id关联,但是经常需要name字段,可以将字段冗余到此表中。(新问题,如何同步name?A: 定时任务、任务通知、触发器)
跨分片数据排序分页
跨库分页查询,排序问题
解决方案:
应用层拼接(组装拼接)
改造
唯一主键问题
用自增id作为主键,而自增id只在但表中唯一,多个表之间有可能重复
解决方案:
UUID,缺点:值太大,影响索引效率
算法生成:snowflke
mongDB,Redis 作为主键,或者使用zookeeper
全局id表
分布式事务问题
多个数据库表之间保证原子性,事务将会导致性能问题。
一般的互联网公司使用强一致性事务比较少。
如何权衡存储优化
提前规划,比如数据量将会在半年指数增长(逐渐问题、join),进行防范
当前数据单表超过1000W,每天的增长量持续上升,此时优化迫切
水平分割
当一个表数据过多时,可以使用表分割。
分表的基本方案:
将qq用户表分为三张表:qqlogin0, qqlogin1, qqlogin2
当创建用户时,将用户id%3 得到一个 >=0 && <3 的数,分别存入不同的表中
当查询用户时,根据用户id%3得到的值,分别去不同的表查询
我们在提供检索时,应该根据业务的需求,找到分表的标准,并在检索页面,约束用户的检索方式。
根据业务需求: 会员
约束检索条件:必须输入到市级别的地址
垂直分割
表的某些字段,在查询时,并不是实时需要关心的,而且数据量又很大,建议可以将这些字段单独提取到另一张表中,保持关联关系,从而提高效率。
最后更新于
这有帮助吗?