forked from cpsing/tddl
-
Notifications
You must be signed in to change notification settings - Fork 17
ComplexRule
agapple edited this page Jan 26, 2014
·
1 revision
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="vtabroot" class="com.taobao.tddl.rule.VirtualTableRoot" init-method="init">
<property name="defaultDbIndex" value="TDDL_DEFAULT_GROUP"/>
<property name="dbType" value="MYSQL"></property>
<property name="tableRules">
<map>
<!-- 按照字符类型的数字串截取分表,分表字段二选一 -->
<entry key="number" value-ref="number_bean"></entry>
<!-- 自定义的规则逻辑,写在java代码中 -->
<entry key="custom" value-ref="custom_bean"></entry>
<!-- 按照gmt_create时间分库分表 -->
<entry key="time" value-ref="time_bean"></entry>
<!-- 按照数字分表,存在特殊映射 -->
<entry key="special" value-ref="soecial_bean"></entry>
<!-- 两个字段分表 -->
<entry key="nani" value-ref="nani_bean"></entry>
</map>
</property>
</bean>
<!-- 按照seller_id和id,二选一分表,优先选择seller_id,为空的情况下使用id
三段式#seller_id,1,1000_1511#第三个参数1000_1511是初始化计算拓扑使用。
该参数默认是分表的总数,例如#seller_id,1,1024#,初始化tddl会枚举0-1023分表进行规则计算,得到应用的全拓扑。
因为这个规则的特殊性,如果tddl还是枚举0-1023可能出现两个问题,第一个是字符串截取越界异常,第二个是枚举不全导致拓扑不全。
因此,这里直接1000_1511这个参数用于直接指定枚举的初始和结束值,避免上面两个问题。
三段式详细内容参见:@com.taobao.tddl.rule.bean.AdvancedParameter
-->
<bean id="time_bean" class="com.taobao.tddl.rule.TableRule">
<property name="dbNamePattern" value="TDDL_GROUP"/>
<property name="tbNamePattern" value="number_{0000}"></property>
<property name="tbRuleArray">
<list>
<value>placeHolder(4, Long.valueOf(#user_id,1,1000_1511#.substring(#user_id,1,1000_1511#.length() - 3,#user_id,1,1000_1511#.length())) % 512)</value>
<value>placeHolder(4, Long.valueOf(#id,1,1000_1511#.substring(#id,1,1000_1511#.length() - 3,#id,1,1000_1511#.length())) % 512)</value>
</list>
</property>
</bean>
<!-- 按照id进行分表
引入用户自定义的类:com.taobao.tddl.rule.le.extrapackage.SelfClass
规则计算调用自定义类中的方法得到返回值:SelfClass.dbCalculate(long id);
-->
<bean id="custom_bean" class="com.taobao.tddl.rule.TableRule">
<property name="extraPackages">
<list>
<value>com.taobao.tddl.rule.le.extrapackage.SelfClass</value>
</list>
</property>
<property name="dbNamePattern" value="GROUP_SNSPART_{00}"/>
<property name="dbRuleArray">
<value>SelfClass.tableCalculate(#id,1,64#)</value>
</property>
<property name="tbNamePattern" value="custom_{0000}"></property>
<property name="tbRuleArray">
<value>SelfClass.dbCalculate(#id,1,64#)</value>
</property>
</bean>
<!-- 按照gmt_create时间分库分表,
分库规则为gmt_create的年份部分填充,例如 TDDL_2013_GROUP
分表规则为gmt_create的天数是当年第几天填充,例如 time_1 -> time_366
注:yyyy(),getCalendar()是tddl提供的静态方法,详见@com.taobao.tddl.rule.groovy.impl.GroovyStaticMethod
-->
<bean id="time_bean" class="com.taobao.tddl.rule.TableRule">
<property name="dbNamePattern" value="TDDL_{0000}_GROUP"/>
<!-- 获取gmt_create的年份 -->
<property name="dbRuleArray">
<value>yyyy(#gmt_create,1_date,366#)</value>
</property>
<!-- 获取gmt_create的Calendar对象(java)并且调用它的java方法获取dayofyear -->
<property name="tbRuleArray">
<value>"time_" + getCalendar(#gmt_create,1_date,366#).get(Calendar.DAY_OF_YEAR)</value>
</property>
</bean>
<!-- 按照user_id数字分表,存在特殊映射,
不分库,全部表存在于TDDL_DEFAULT_GROUP中
def id = xxx, 是groovy定义变量的语法,rule里面是可以写代码的哦。
注:placeHolder()是tddl提供的静态方法,详见@com.taobao.tddl.rule.groovy.impl.GroovyStaticMethod
-->
<bean id="soecial_bean" class="com.taobao.tddl.rule.TableRule">
<property name="dbNamePattern" value="TDDL_DEFAULT_GROUP"/>
<property name="tbRuleArray">
<value>
def id = #user_id,1,128#.longValue();
if(id == 10){
return "special_vip";
}
else {
return "special_" + placeHolder(4, id % 128) ;
}
</value>
</property>
</bean>
<!-- 按照gmt_create和id两个字段进行分表
不分库,全部表存在于TDDL_DEFAULT_GROUP中
规则直接拼出表名的字符串。
-->
<bean id="nani_bean" class="com.taobao.tddl.rule.TableRule">
<property name="dbNamePattern" value="TDDL_DEFAULT_GROUP"/>
<property name="tbRuleArray">
<value>
"nani_" + mm(#gmt_create,1_date,366#) + "_" + placeHolder(2,#id,1,16#.longValue() % 16);
</value>
</property>
</bean>
<!--
对于规则中的分表字段表示方式 #gmt_create,1_date,366# 的解释
#gmt_create,1_date,31#一共分为3个部分,各个部分之间以逗号','隔开。
第一部分:gmt_create 表示分表字段名。
第二部分:1_date 表示枚举的跨度是1天。(范围查询用)
第三部分:31 表示枚举的最大数量是31次。(范围查询用)
例如:表规则是 "table_" + date(#gmt_create,1_date,31#), sql条件是gmt_create <= "2013-11-14 10:10:10"
tddl需要枚举可能出现的时间点用于规则计算。
首先拿到当前时间 "2013-11-14 10:10:10" 计算"table_" + date("2013-11-14 10:10:10") = table_14 (date()函数详见@com.taobao.tddl.rule.groovy.impl.GroovyStaticMethod)
接着将时间减去一个跨度 1_date 得到 "2013-11-13 10:10:10" 计算规则得到结果 = table_13
.
.
.
直到枚举到最大次数达到31次,也就是 "2013-10-14 10:10:10" 计算规则得到结果 = table_14
最终得到一个计算结果的集合(table_01-31),也即是这次查询应该要遍历的表的名字的集合
-->
</beans>