分库分表后,首先要解决数据库路由问题,要到哪个库去获取或者变更数据,是多库路由还是单库路由。同时要解决分表问题,路由到指定的表或者全部的表。
比如以下场景:
先假设分片如下:
所有数据源配置:
db_defualt 现有数据库
db_0_0 个人用户账户分片组0 数据库0
db_0_1 个人用户账户分片组0 数据库1
db_1_0 商户账户分片组1 数据库0
db_1_1 商户账户分片组1 数据库1
账户id:
现在算法:15位序号+1位校验位,长度为16位
改造后算法:15位序号+1位校验位+1位分片组编号基因+1位分片组内分片编号基因,长度变为18位
路由算法:
if(id是16位){
db = db_defualt(现在的库);
}else if(id是18位){
db = db_{id倒数第二位}_{id倒数第一位}
}
账户余额变动流水id:
现在算法:16序列+4位随机数,长度变为20位
改造后算法:16序列+3位随机数+账户id后2位分库基因,长度变为21位
db路由算法:
if(id是20位){
db = db_defualt(现在的库);
}else if(id是21位){
db = db_{id倒数第二位}_{id倒数第一位}
}
1,根据账户id查询单账户信息。插入和修改账户信息路由相同。
根据分布式id设计规则,账户分布在某个分库下面,这个时候需要根据路由算法路由到指定的库(即拿对应datasource 的connection执行sql)
SELECT * FROM ACCOUNT T WHERE T.ACCOUNTID = '0000000008072027' 根据路由算法16位路由到db_default
SELECT * FROM ACCOUNT T WHERE T.ACCOUNTID = '000000000807202701' 18位后两位决定路由,路由到db_0_1
2,查询某个商户下面所有的账户。
水平分库后,账户可能根据id规则分布在不同的数据库中,这个时候需要路由到所有的数据库中执行查询。
select * from ACCOUNT t WHERE T.CUSTID = '0000000000012345' and currenty='CNY' AND ACCOUNT_TYPE='01' AND SEQ=1
查询条件中没有账户id,不能根据账户id进行路由到指定的库,这个时候需要全部分库都执行一遍查询。
根据上面5个数据源配置,路由到5个数据库,并发执行5个sql查询,结果归并。
3,查询某个商户下面所有的账户可提现余额汇总(不可提现余额,授信使用余额,授信额度汇总)。
水平分库后,账户可能根据id规则分布在不同的数据库中,这个时候需要路由到所有的数据库中执行查询。
select sum(account.uncash_amount) CreditLine from Account account where account.custid='0000000000012345';
select sum(account.uncash_amount - account.freeze_uncashamount - account.hold_uncashamount ) uncashamount from Account account
where account.custid='0000000000012345'(待验证)
查询条件中没有账户id,不能根据账户id进行路由到指定的库,这个时候需要全部分库都执行一遍查询。
根据上面5个数据源配置,路由到5个数据库,并发执行5个sql查询,结果归并。