mysql 分库分表 建表_【分库分表】sharding-jdbc实践—分库分表入门
一、准备工作
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实践—分库分表入门相关推荐
- 光动能表怎么维护_光动能手表是什么意思(一个修表师傅的忠告)
最佳答案 光动能 是西铁城的专利技术和注册商标,指内置光能充电电池的石英表,只要有光就能给表充电. 最佳答案 光动能 也是用电池的,不过是充电的,利用光充用,充满一次可以用半年.电池的寿命有长短,好的 ...
- sharding jdbc:分库、分表;读写分离;
1 转载于:https://www.cnblogs.com/cnki/p/8835764.html
- mysql 表名 参数化_我可以在准备好的语句中参数化表名吗?
我可以在准备好的语句中参数化表名吗? 我多次使用mysqli_stmt_bind_param函数.但是,如果我将试图防止SQL注入的变量分开,则会遇到错误. 下面是一些代码示例:function in ...
- 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 ...
- sharding jdbc根据年月分表
1.配置Maven依赖 <!--shardingsphere分表策略--> <dependency><groupId>io.shardingsphere</g ...
- html表单居中_如何在IE低版本中兼容HTML5表单属性placeholder属性
WEB开发数据提交是必不可少的,为了更友好的用户体验,通常需要给输入框一个默认的提示信息.HTML5技术提供了一个表单属性placeholder专门用于输入框默认提示,但是在IE低版本中根本不兼容. ...
- 查看表结构索引_索引策略–第1部分–选择正确的表结构
查看表结构索引 介绍 (Introduction) Among many different things that can affect SQL Server performance, some a ...
- 千牛包表包下载_带有服务器端处理和VueJS组件的数据表包
千牛包表包下载 Vue数据表 (Vue Data Table) Data Table package with server-side processing and VueJS components. ...
- mysql workbench 从model建库_使用MySQL Workbench进行数据库设计——MySQL Workbench用法总结...
转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/48318877 本文出自[我是干勾鱼的博客] 1 简单介绍 MySQL Workb ...
- 分别是什么意思_美国FBA头程:空派/海派分别是什么意思?
美国FBA头程:空派.海派分别是什么意思?空派,也被称为空加派,是美国路向的一种FBA头程运输方式.先将货物集中装机运输到美国,抵达.清关之后,再转交末端承运商负责派送至最终的亚马逊FBA仓库.常见的 ...
最新文章
- 電子商務新紀元-WebService With BizSnap
- 【138天】尚学堂高淇Java300集视频精华笔记(84)
- python 并行计算 并行方法总结 concurrent.futures pp pathos multiprocessing multiprocess模块 总结对比
- ubifs linux,ubifs使用方法
- 信息收集——子域名收集
- 【云服务】云服务案例分析Quiz
- linux 邮件附件 中文,linux bash下通过mailx发送中文内容显示为附件的解决
- 页面背景图尺寸不随浏览器缩放而变化
- volte 是什么意思
- java--基本数据类型的转换(强制转换)
- JS删除两个数组中相同的某个对象值
- java扫码盒_[腾讯 TMQ] JAVA 代码覆盖率工具 JaCoCo-实践篇
- Boruta特征筛选
- “2021年度全球十大人工智能治理事件”:数据、算法、伦理受关注,AI发展需治理同行
- 一图区分1.85mm/2.4mm/2.92mm/3.5mm/SMA射频接头
- UG软件使用10大技巧,将会大大提升工作效率
- 周董演唱会为什么总是抢不到票?教你用Python做一个自动抢票脚本
- 到极地拍摄北极熊 你需要这样的装备
- Abnova 基因 FISH 探针丨CCND1(橙色)FISH 探针
- 【计算机组成与结构】中央处理器
热门文章
- R语言scale_colour_brewer()函数和scale_fill_brewer()函数调色板及填充ggplot2图像实战
- 为什么需要权重初始化(weight initialization)?常见的权重初始化方式有哪些?启发式权重初始化的好处?
- android studio怎么输出文本,Android Studio 如何获取 text文本内容
- 生信分析必须了解的4种文件格式
- 阿里云云服务器ECS上的Ubuntu16.04桌面安装及root账户登录错误处理
- 论文笔记 Inter-sentence Relation Extraction with Document-level Graph Convolutional Neural Network
- pytroch 数据集 datasets DataLoader示例
- windows10 删除文件 的权限才能对此文件夹进行更改 解决办法
- Python局域网socket无法连接的问题解决
- 查看ocx控件CLSID的方法