利用sharding-jdbc分库分表
2016-02-22 15:25
405 查看
sharding-jdbc是当当开源的一款分库分表的数据访问层框架,能对mysql很方便的分库、分表,基本不用修改原有代码,只要配置一下即可,完整的配置参考以下内容:
View Code
然后mybatis里就可以类似常规操作一样来写sql了,具体可参考源码中的示例代码。
不过,经个人测试发现一些小问题,以避免大家踩坑:
1、聚合函数的使用要特别小心,我试了下max/min/count这几个函数,返回时记得给返回结果加字段别名,即: select count(*) order_count from t_order,否则可能返回的结果不正确(已经向作者反馈,估计很快会修复该bug)
2、另外分库的key,不支持范围搜索,类似 select * from t_order where user_id > 100的操作,直接报错,如果需要这样的操作,建议先取max(user_id),比如最大用户id为120,然后user_id in (101,102...120) 或者 between ... and 这样处理。
3、如果采用druid数据源,目前有点不稳定,偶尔会出异常,建议采用dbcp(跟作者反馈了下,说是很快会修复该问题)
4、批量插入问题,insert xxx values(...),(...),(...) 不支持,主要原因是因为要插入的记录,无法定位分片。但是可以适当预处理下变通解决,思路:按db-key将List<T>中的对象先划分成Map<dbkey,List<T>>,然后每个entry的List<T>再按tableKey做同样的map映射,即:将List<T>变成Map<dbkey,Map<tableKey,List<T>> 这种结构,相当于人工把同一分片的数据整理到一起,再做insert批量插入就可以了。
其它一些使用上的限制,参考:
http://dangdangdotcom.github.io/sharding-jdbc/post/limitations/
最后,我在github上放了一个示例代码sharding-jdbc-sample,需要的同学可以参考
/** * Copyright 1999-2015 dangdang.com. * <p> * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p/> * http://www.apache.org/licenses/LICENSE-2.0 * <p/> * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * </p> */ package com.cnblogs.yjmyzz.sharding.algorithm; import com.dangdang.ddframe.rdb.sharding.api.ShardingValue; import com.dangdang.ddframe.rdb.sharding.api.strategy.table.SingleKeyTableShardingAlgorithm; import com.google.common.collect.Range; import java.util.Collection; import java.util.LinkedHashSet; public final class SingleKeyModuloTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Integer> { private int tableCount = 1; @Override public String doEqualSharding(final Collection<String> availableTargetNames, final ShardingValue<Integer> shardingValue) { for (String each : availableTargetNames) { if (each.endsWith(shardingValue.getValue() % tableCount + "")) { return each; } } throw new UnsupportedOperationException(); } @Override public Collection<String> doInSharding(final Collection<String> availableTargetNames, final ShardingValue<Integer> shardingValue) { Collection<String> result = new LinkedHashSet<>(availableTargetNames.size()); Collection<Integer> values = shardingValue.getValues(); for (Integer value : values) { for (String tableNames : availableTargetNames) { if (tableNames.endsWith(value % tableCount + "")) { result.add(tableNames); } } } return result; } @Override public Collection<String> doBetweenSharding(final Collection<String> availableTargetNames, final ShardingValue<Integer> shardingValue) { Collection<String> result = new LinkedHashSet<>(availableTargetNames.size()); Range<Integer> range = shardingValue.getValueRange(); for (Integer i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) { for (String each : availableTargetNames) { if (each.endsWith(i % tableCount + "")) { result.add(each); } } } return result; } /** * 设置分表的个数 * * @param tableCount */ public void setTableCount(int tableCount) { this.tableCount = tableCount; } }
View Code
然后mybatis里就可以类似常规操作一样来写sql了,具体可参考源码中的示例代码。
不过,经个人测试发现一些小问题,以避免大家踩坑:
1、聚合函数的使用要特别小心,我试了下max/min/count这几个函数,返回时记得给返回结果加字段别名,即: select count(*) order_count from t_order,否则可能返回的结果不正确(已经向作者反馈,估计很快会修复该bug)
2、另外分库的key,不支持范围搜索,类似 select * from t_order where user_id > 100的操作,直接报错,如果需要这样的操作,建议先取max(user_id),比如最大用户id为120,然后user_id in (101,102...120) 或者 between ... and 这样处理。
3、如果采用druid数据源,目前有点不稳定,偶尔会出异常,建议采用dbcp(跟作者反馈了下,说是很快会修复该问题)
4、批量插入问题,insert xxx values(...),(...),(...) 不支持,主要原因是因为要插入的记录,无法定位分片。但是可以适当预处理下变通解决,思路:按db-key将List<T>中的对象先划分成Map<dbkey,List<T>>,然后每个entry的List<T>再按tableKey做同样的map映射,即:将List<T>变成Map<dbkey,Map<tableKey,List<T>> 这种结构,相当于人工把同一分片的数据整理到一起,再做insert批量插入就可以了。
其它一些使用上的限制,参考:
http://dangdangdotcom.github.io/sharding-jdbc/post/limitations/
最后,我在github上放了一个示例代码sharding-jdbc-sample,需要的同学可以参考
相关文章推荐
- 利用JS实现手机访问PC网址自动跳转到wap网站
- python生成器
- iOS UTI(统一类型标识)
- 个人遇到的SQL错误零散汇总
- jboss之404错误
- ListView 批量删除、数据库同步
- spring-jdbc文件数据库配置加密
- Android UI效果之绘图篇(二):Canvas
- ubuntu下配置tomcat服务器
- Files 的值“ < < < < < < < .mine”无效。路径中具有非法字符。
- 移动端图片操作——上传
- 【monkeyrunner】monkeyrunner 实例
- Laravel 文档中的 Service Providers
- LeetCode Longest Substring Without Repeating Characters
- Cookie/Session机制详解
- 函数
- binary search---Sqrt(x)
- svg动画
- Markdown中插入数学公式的方法
- hdu 2610 Sequence one【搜索 dfs+剪枝】