Skip to content
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>

Clone this wiki locally