基于 Range 的分片方式
优质
小牛编辑
129浏览
2023-12-01
配置
在使用range分表函数前先了解 分库分表规则原理及自定义配置,range分表与普通规则基本原理相同,只是配置略有不同。根据range的分库分表与原有的稍有不同,具体的规则的xml格式及在管理平台上配置后最后存储的格式其实如下:
<?xml version="1.0" encoding="UTF-8"?>
<router-rule>
<table-shard-rule table="TestTable" global="false">
<shard-dimension
<!--分表键createtime需要是Date或String-->
dbRule="shardByMonth(#createtime#, 'yyyy-MM-dd', '2010-01-10', '2013-12-20', 6, 2, 4, 0, 4)"
dbIndexes="database[0-1]"
tbRule="" <!--物理表路由规则暂时需要留空(只有使用shardByMonth或shardById等内置特殊范围分表函数时留空)-->
tbSuffix="everydb:[0,3]&database0:[$]"
isMaster="true">
</shard-dimension>
</table-shard-rule>
</router-rule>
路由规则
目前支持两种规则:根据日期或id(整数)进行分库分表
/**
* shardValues: shard字段(类型需要是Date或对应格式的String)
* dateFormat: 默认日期格式
* inclusiveStartTime: shard开始时间(年月日, 格式和dateFormat相同,注意开始和结束范围为闭区间)
* inclusiveEndTime: shard结束时间(年月日, 格式和dateFormat相同)
* monthCountPerTable: 几个月一张表
* databaseCount: 分库数量(如果默认库是单独的则不包含在内)
* tableCountPerDb: 每个库分表数量(如果默认表是单独的则不包含在内)
* defaultDbIndex: shard范围外默认库(指在配置时间范围外的数据路由到哪个库)
* defaultTableIndex: shard范围外默认表(指在配置时间范围外的数据路由到哪个表)
* useDefaultOrder: 是否使用默认顺序
*/
//使用默认顺序
shardByMonth(Object shardValues, String dateFormat, String inclusiveStartTime, String inclusiveEndTime,
int monthCountPerTable, int databaseCount, int tableCountPerDb, int defaultDbIndex, int defaultTableIndex)
// true--默认熟悉,false--交叉分布
shardByMonth(Object shardValues, String dateFormat, String inclusiveStartTime, String inclusiveEndTime,
int monthCountPerTable, int databaseCount, int tableCountPerDb, int defaultDbIndex, int defaultTableIndex, boolean useDefaultOrder)
/**
* shardValues: shard字段(需要是整数)
* start: shard开始的数值(注意开始和结束范围为闭区间)
* end: shard结束的数值
* countPerTable: 每张表的数值范围
* tableCountPerDb: 每个库分表数量(如果默认表是单独的则不包含在内)
* databaseCount: 分库数量(如果默认库是单独的则不包含在内)
* defaultDbIndex: shard范围外默认库(指在配置数值范围外的额外数据路由到哪个库)
* defaultTableIndex: shard范围外默认表(指在配置数值范围外的额外数据路由到哪个表)
* useDefaultOrder: 是否使用默认顺序
*/
//使用默认顺序
shardByLong(Object shardValues, long start, long end, int countPerTable, int tableCountPerDb, int databaseCount,
int defaultDbIndex, int defaultTableIndex)
shardByLong(Object shardValues, long start, long end, int countPerTable, int tableCountPerDb, int databaseCount,
int defaultDbIndex, int defaultTableIndex, boolean useDefaultOrder)
注意:
- 目前shardByMonth、shardById暂不支持shardKey的or语句
- 使用shardByMonth、shardById时,只需配库规则,表规则留空
- shardByMonth、shardById中配置的时间或数值范围为闭区间
排序规则
有两个库db0、db1,每个库有 tb0-3 四个表,假设根据id进行分表,每张表100条数据
默认排列 | 交叉排列 | |||||
---|---|---|---|---|---|---|
id范围 | db | tb | id | db | tb | |
0-99 | db0 | tb0 | 0-99 | db0 | tb0 | |
100- 199 | db0 | tb1 | 100-199 | db1 | tb0 | |
200 -299 | db0 | tb2 | 200 -299 | db0 | tb1 | |
300-399 | db0 | tb3 | 300-399 | db1 | tb1 | |
400-499 | db1 | tb0 | 400-499 | db0 | tb2 | |
500-599 | db1 | tb1 | 500-599 | db1 | tb2 | |
600-699 | db1 | tb2 | 600-699 | db0 | tb3 | |
700-799 | db1 | tb3 | 700-799 | db1 | tb3 | |
800-899 | db0 | tb0 | 800-899 | db0 | tb0 |
实例
a.库路由规则:
shardByMonth(#createtime#, 'yyyy-MM-dd', '2010-01-10', '2013-12-20', 6, 2, 4, 0, 4)
物理库索引: "database[0-1]"
表后缀名: everydb:[0,3]&database0:[$]
0库5张表,1库4张表,2010-01-10 -- 2013-12-20 6个月一张表,超出时间范围的数据映射到0库上第5张表上,
使用默认顺序 2010-01-10 -- 2011-12-31 在0库,2012-01-01 -- 2013-12-20 在1库,其他在0库默认表
b.库路由规则:
shardByMonth(#createtime#, 'yyyy-MM-dd', '2010-01-10', '2013-12-20', 6, 2, 4, 0, 4, false)
2010-01-10 -- 2010-06-30 0库0表
2010-07-01 -- 2010-12-31 1库0表
2011-01-01 -- 2011-06-30 0库1表
2011-07-01 -- 2011-12-31 1库1表
2012-01-01 -- 2012-06-30 0库2表
2012-07-01 -- 2012-12-31 1库2表
2013-01-01 -- 2013-06-30 0库3表
2013-07-01 -- 2013-12-31 1库3表