分库分表实践

本文探讨了数据库分库分表的必要性,由于数据量增长带来的性能瓶颈问题。介绍了两种分库分表策略:垂直切分和水平切分。重点讲述了水平切分的实践,通过userId的特定位数进行分库分表,并展示了配置拦截器和多数据源选择的逻辑,将这些逻辑集中在DAO的父类中。

1、为什么要分库分表?

数据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,表中的数据量会越来越大,相应地,数据操作,增删改查的开销也会越来越大;另外一个DB所能承载的数据量、数据处理能力都会成为瓶颈。

2、 分库分表实施策略

分库分表有垂直切分和水平切分两种

1)垂直切分即将表按照功能模块、关系密切程度划分,并部署到不同的库上。例如,商品信息和交易信息适合单独存放。

2)水平切分即当一个表中数据量过大时,可以把该表的数据按照某种规则,例如userID散列,进行划分,然后存储到多个结构相同的表,和不同的库上。


水平切分实践代码:userId为10位数字字符串,第8位表述分表位,第9位表示分库位。

public class DAORouteInterceptor implements MethodInterceptor {
    /** table index in userId */
    public static int TABLE_INDEX = 8;
    /** db index in userId */
    public static int DB_INDEX    = 9;
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object[] args = invocation.getArguments();
        String userId = (String) args[args.length - 2];
        args[args.length - 2] = parseTableIndexByUserId(userId);
        args[args.length - 1] = parseDBIndexByUserId(userId);
        return invocation.proceed();
    }
    /**
     * parser tableIndex with userId
     * 
     * @param userId unique id of user
     * @return id of table
     */
    public static int parseTableIndexByUserId(String userId) {
        String tableIndex = StringUtil.substring(userId, TABLE_INDEX, TABLE_INDEX + 1);
        return Integer.valueOf(tableIndex);
    }
    /**
     * parser dbIndex with userId
     * 
     * @param userId unique id of user 
     * @return id of db
     */
    public static int parseDBIndexByUserId(String userId) {
        String dbIndex = StringUtil.substring(userId, DB_INDEX, DB_INDEX + 1);
        return Integer.valueOf(dbIndex);
    }
}


配置拦截器

切换所有分库分表计算逻辑放在DAO的父类BaseDAO的routeParser方法里。配置多数据源,根据表ID和库ID选择数据源的逻辑也放在BaseDAO里。子类DAO调用父类方法,拦截器拦截父类的分库分表方法。

拦截器配置如下:

	<!-- DAO sql route parser interceptor -->
	<bean id="daoRouteProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="interceptorNames">
			<list>
				<value>daoRouteInterceptor</value>
			</list>
		</property>
		<property name="beanNames">
			<value>BaseDAO</value>
		</property>
	</bean>
	<bean id="daoRouteInterceptor" class="com.test.interceptor.DAORouteInterceptor" />
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值