zhuanlan.zhihu.com/p/143072827
数据库瓶颈
拆分方案
range, hash, 时间
水平 垂直
-
水平分库 以字段为依据,按照一定策略(hash、range等),将一个库中的数据拆分到多个库中。
-
水平分表 以字段为依据,按照一定策略(hash、range等),将一个表中的数据拆分到多个表中。
-
垂直分库 以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。
-
垂直分表 以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。
非partition key的查询问题
端上除了partition key只有一个非partition key作为条件查询
映射法
基因法
注:写入时,基因法生成user_id,如图。关于xbit基因,例如要分8张表,23=8,故x取3,即3bit基因。根据user_id查询时可直接取模路由到对应的分库或分表。根据user_name查询时,先通过user_name_code生成函数生成user_name_code再对其取模路由到对应的分库或分表。id生成常用snowflake算法。
端上除了partition key不止一个非partition key作为条件查询
映射法
es
数据迁移问题
-
很多情况下并不是一开始就实现分库分表,等我们需要分库分表的时候如何进行数据迁移?
-
建表
-
代码双写(之前所有对数据库增删改的操作,除了对老库增删改,都加上对新库的增删改)
-
脚本迁移数据到新库(如果读出来的数据在新库里没有,或者这条数据的update_time最后修改的时间,比新库的数据新才会写。简单来说,就是不允许用老数据覆盖新数据。)
-
check数据(导完一轮之后,有可能数据还是存在不一致,那么就程序自动做一轮校验,对比新老库每个表的每条数据,如果有不一样的,就针对那些不一样的,从老库读数据再次写。反复循环,直到两个库每个表的数据都完全一致为止。)
-
数据完全一致后,用分库分表的最新代码,下双写逻辑
跨库Join的几种解决思路
-
全局表 所谓全局表,就是有可能系统中所有模块都可能会依赖到的一些表。比较类似我们理解的“数据字典”。为了避免跨库join查询,我们可以将这类表在其他每个数据库中均保存一份。同时,这类数据通常也很少发生修改(甚至几乎不会),所以也不用太担心“一致性”问题。
-
字段冗余
-
数据同步,定时A库中的tab_a表和B库中tbl_b有关联,可以定时将指定的表做同步。
-
系统层组装