一、准备工作

1、准备三个数据库:db0、db1、db2

2、每个数据库新建两个订单表:t_order_0、t_order_1

DROP TABLE IF EXISTS`t_order_x`;CREATE TABLE `t_order_x` (

`id`bigint NOT NULLAUTO_INCREMENT,

`user_id` bigint NOT NULL,

`order_id`bigint NOT NULL,

`order_no`varchar(30) NOT NULL,

`isactive`tinyint NOT NULL DEFAULT ‘1‘,

`inserttime`datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,

`updatetime`datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY(`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

二、分库分表配置

数据源的配置可以使用任何链接池,本例用druid为例。

1、引言依赖包:

引用最新的maven包

2.0.1

io.shardingjdbc

sharding-jdbc-core

${sharding-jdbc.version}

2、配置DataSource:

@Bean(name = "shardingDataSource", destroyMethod = "close")@Qualifier("shardingDataSource")publicDataSource getShardingDataSource() {//配置真实数据源

Map dataSourceMap = new HashMap<>(3);//配置第一个数据源

DruidDataSource dataSource1=createDefaultDruidDataSource();

dataSource1.setDriverClassName("com.mysql.jdbc.Driver");

dataSource1.setUrl("jdbc:mysql://localhost:3306/db0");

dataSource1.setUsername("root");

dataSource1.setPassword("root");

dataSourceMap.put("db0", dataSource1);//配置第二个数据源

DruidDataSource dataSource2=createDefaultDruidDataSource();

dataSource2.setDriverClassName("com.mysql.jdbc.Driver");

dataSource2.setUrl("jdbc:mysql://localhost:3306/db1");

dataSource2.setUsername("root");

dataSource2.setPassword("root");

dataSource2.setName("db1-0001");

dataSourceMap.put("db1", dataSource2);//配置第三个数据源

DruidDataSource dataSource3=createDefaultDruidDataSource();

dataSource3.setDriverClassName("com.mysql.jdbc.Driver");

dataSource3.setUrl("jdbc:mysql://localhost:3306/db2");

dataSource3.setUsername("root");

dataSource3.setPassword("root");

dataSourceMap.put("db2", dataSource3);//配置Order表规则

TableRuleConfiguration orderTableRuleConfig=new TableRuleConfiguration();

orderTableRuleConfig.setLogicTable("t_order");

orderTableRuleConfig.setActualDataNodes("db${0..2}.t_order_${0..1}");//orderTableRuleConfig.setActualDataNodes("db0.t_order_0,db0.t_order_1,db1.t_order_0,db1.t_order_1,db2.t_order_0,db2.t_order_1");//配置分库策略(Groovy表达式配置db规则)

orderTableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id", "db${user_id % 3}"));//配置分表策略(Groovy表达式配置表路由规则)

orderTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order_${order_id% 2}"));//配置分片规则

ShardingRuleConfiguration shardingRuleConfig=new ShardingRuleConfiguration();

shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);//配置order_items表规则...//获取数据源对象

DataSource dataSource= null;

try {

dataSource=ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, new ConcurrentHashMap(), new Properties());

} catch (SQLException e) {

e.printStackTrace();

}returndataSource;

}

可以使用Druid监控db。

三、示例验证

1、新增数据

@Slf4j

@RestController

@RequestMapping("/order")public classOrderController {

@AutowiredprivateOrderMapper orderMapper;

@RequestMapping("/add")public voidaddOrder() {

OrderEntity entity10= newOrderEntity();

entity10.setOrderId(10000L);

entity10.setOrderNo("No1000000");

entity10.setUserId(102333001L);

orderMapper.insertSelective(entity10);

OrderEntity entity11= newOrderEntity();

entity11.setOrderId(10001L);

entity11.setOrderNo("No1000000");

entity11.setUserId(102333000L);

orderMapper.insertSelective(entity11);

}

}

依据配置的分片规则

DB路由规则:user_id % 3:

102333001 % 3 = 1

102333000 % 3 = 0

表路由规则:order_id % 2:

10000 % 2 = 0

10001 % 2 = 1

userid=102333001,orderId=10000的数据落地到db1.t_order_0

userid=102333000,orderId=10001的数据落地到db0.t_order_1

2、未指定分片规则字段的查询

/**广播遍历所有的库和表*/@RequestMapping("get")public voidgetOrder() {

List ids = new ArrayList<>();

ids.add(4);

List orderEntities =orderMapper.selectByPrimaryIds(ids);

log.info(JSON.toJSONString(orderEntities));

}

由druid监控sql得知,查询被广播到db0、db1、db2的各个表里,如下监控所示:

3、不能执行批量插入操作

不支持对不同分片规则的字段值进行批量插入操作,类似sql:insert into t_order values(x,x,x,x),(x,x,x,x),(x,x,x,x)

4、谨慎修改分片规则字段

如果修改了分片规则的字段,比如本例的user_id或order_id,因为路由规则会造成数据存在,却查不到数据的情况。

@RequestMapping("/upd")public voidupdate() {

OrderEntity orderWhere= newOrderEntity();

orderWhere.setOrderId(10001L);

orderWhere.setUserId(102333001L);

orderWhere.setId(4L);

OrderEntity orderSet= newOrderEntity();

orderSet.setOrderId(10002L);

orderSet.setOrderNo("修改订单号");

orderMapper.updateByPredicate(orderSet, orderWhere);/**查不到,orderId更改会引起路由查询失败*/OrderEntity predicate= newOrderEntity();

predicate.setOrderId(10002L);

OrderEntity entity=orderMapper.selectSingleByPredicate(predicate);

log.info("after update orderEntity:"+JSON.toJSONString(entity));

}

四、sharding建表

目前配置并验证了3个库,每库2个order表的场景:

如果分库分表数量比较多,仅仅创建表就是一件很繁琐的事情。sharding查询数据不指定分片规则字段时,会自动路由到各个库的各个表里查询,不知道大家有没有想到:如果配置要创建表的路由规则,用sharding来执行一条创建sql的语句,会不会就自动路由到各个库去执行了,也就代替人工去各个库建表了呢?下面来验证一下这个想法,以创建t_order_items表为例:

1、配置t_order_items的规则:

在上面配置t_order规则下面补充t_order_items的规则配置:

//省略配置order_item表规则...

TableRuleConfiguration orderItemTableRuleConfig = newTableRuleConfiguration();

orderItemTableRuleConfig.setLogicTable("t_order_items");

orderItemTableRuleConfig.setActualDataNodes("db${0..2}.t_order_items_${0..1}");//配置分库策略

orderItemTableRuleConfig.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "db${order_id % 3}"));//配置分表策略

orderItemTableRuleConfig.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id", "t_order_items_${order_id % 2}")); shardingRuleConfig.getTableRuleConfigs().add(orderItemTableRuleConfig);

2、t_order_items建表sql语句:

CREATE TABLE IF NOT EXISTS `t_order_items` (

`id` bigint NOT NULL AUTO_INCREMENT,

`order_id` bigint NOT NULL,

`unique_no` varchar(32) NOT NULL,

`quantity` int NOT NULL DEFAULT ‘1‘,

`is_active` tinyint NOT NULL DEFAULT 1,

`inserttime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,

`updatetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、OrderItemsMapper方法:

Integer createTItemsIfNotExistsTable();

4、执行方法:

orderItemsMapper.createTItemsIfNotExistsTable();

查看db0、db1、db2:

验证了我们上面的想法,建表成功了。

附录

如果没有配置t_order_items规则,执行建表sql会报错:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException:

### Error updating database. Cause: io.shardingjdbc.core.exception.ShardingJdbcException: Cannot find table rule and default data source with logic table: ‘t_order_items‘

### The error may involve defaultParameterMap

### The error occurred while setting parameters

### SQL: CREATE TABLE IF NOT EXISTS `t_order_items` ( `id` bigint NOT NULL AUTO_INCREMENT, `order_id` bigint NOT NULL, `unique_no` varchar(32) NOT NULL, `quantity` int NOT NULL DEFAULT ‘1‘, `is_active` tinyint NOT NULL DEFAULT 1, `inserttime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `updatetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

### Cause: io.shardingjdbc.core.exception.ShardingJdbcException: Cannot find table rule and default data source with logic table: ‘t_order_items‘

mysql 分库分表 建表_【分库分表】sharding-jdbc实践—分库分表入门相关推荐

  1. 光动能表怎么维护_光动能手表是什么意思(一个修表师傅的忠告)

    最佳答案 光动能 是西铁城的专利技术和注册商标,指内置光能充电电池的石英表,只要有光就能给表充电. 最佳答案 光动能 也是用电池的,不过是充电的,利用光充用,充满一次可以用半年.电池的寿命有长短,好的 ...

  2. sharding jdbc:分库、分表;读写分离;

    1 转载于:https://www.cnblogs.com/cnki/p/8835764.html

  3. mysql 表名 参数化_我可以在准备好的语句中参数化表名吗?

    我可以在准备好的语句中参数化表名吗? 我多次使用mysqli_stmt_bind_param函数.但是,如果我将试图防止SQL注入的变量分开,则会遇到错误. 下面是一些代码示例:function in ...

  4. mysql中输出100内质数_输出100以内的所有质数--九九乘法表--作业

    set serverout on declare flag boolean; begin for i in 2..100 loop flag:=true; for j in 2..i-1 loop i ...

  5. sharding jdbc根据年月分表

    1.配置Maven依赖 <!--shardingsphere分表策略--> <dependency><groupId>io.shardingsphere</g ...

  6. html表单居中_如何在IE低版本中兼容HTML5表单属性placeholder属性

    WEB开发数据提交是必不可少的,为了更友好的用户体验,通常需要给输入框一个默认的提示信息.HTML5技术提供了一个表单属性placeholder专门用于输入框默认提示,但是在IE低版本中根本不兼容. ...

  7. 查看表结构索引_索引策略–第1部分–选择正确的表结构

    查看表结构索引 介绍 (Introduction) Among many different things that can affect SQL Server performance, some a ...

  8. 千牛包表包下载_带有服务器端处理和VueJS组件的数据表包

    千牛包表包下载 Vue数据表 (Vue Data Table) Data Table package with server-side processing and VueJS components. ...

  9. mysql workbench 从model建库_使用MySQL Workbench进行数据库设计——MySQL Workbench用法总结...

    转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/48318877 本文出自[我是干勾鱼的博客] 1 简单介绍 MySQL Workb ...

  10. 分别是什么意思_美国FBA头程:空派/海派分别是什么意思?

    美国FBA头程:空派.海派分别是什么意思?空派,也被称为空加派,是美国路向的一种FBA头程运输方式.先将货物集中装机运输到美国,抵达.清关之后,再转交末端承运商负责派送至最终的亚马逊FBA仓库.常见的 ...

最新文章

  1. 電子商務新紀元-WebService With BizSnap
  2. 【138天】尚学堂高淇Java300集视频精华笔记(84)
  3. python 并行计算 并行方法总结 concurrent.futures pp pathos multiprocessing multiprocess模块 总结对比
  4. ubifs linux,ubifs使用方法
  5. 信息收集——子域名收集
  6. 【云服务】云服务案例分析Quiz
  7. linux 邮件附件 中文,linux bash下通过mailx发送中文内容显示为附件的解决
  8. 页面背景图尺寸不随浏览器缩放而变化
  9. volte 是什么意思
  10. java--基本数据类型的转换(强制转换)
  11. JS删除两个数组中相同的某个对象值
  12. java扫码盒_[腾讯 TMQ] JAVA 代码覆盖率工具 JaCoCo-实践篇
  13. Boruta特征筛选
  14. “2021年度全球十大人工智能治理事件”:数据、算法、伦理受关注,AI发展需治理同行
  15. 一图区分1.85mm/2.4mm/2.92mm/3.5mm/SMA射频接头
  16. UG软件使用10大技巧,将会大大提升工作效率
  17. 周董演唱会为什么总是抢不到票?教你用Python做一个自动抢票脚本
  18. 到极地拍摄北极熊 你需要这样的装备
  19. Abnova 基因 FISH 探针丨CCND1(橙色)FISH 探针
  20. 【计算机组成与结构】中央处理器

热门文章

  1. R语言scale_colour_brewer()函数和scale_fill_brewer()函数调色板及填充ggplot2图像实战
  2. 为什么需要权重初始化(weight initialization)?常见的权重初始化方式有哪些?启发式权重初始化的好处?
  3. android studio怎么输出文本,Android Studio 如何获取 text文本内容
  4. 生信分析必须了解的4种文件格式
  5. 阿里云云服务器ECS上的Ubuntu16.04桌面安装及root账户登录错误处理
  6. 论文笔记 Inter-sentence Relation Extraction with Document-level Graph Convolutional Neural Network
  7. pytroch 数据集 datasets DataLoader示例
  8. windows10 删除文件 的权限才能对此文件夹进行更改 解决办法
  9. Python局域网socket无法连接的问题解决
  10. 查看ocx控件CLSID的方法