Sharding-JDBC:单库分表的实现
剧情回顾
前面,我们一共学习了读写分离,垂直拆分,垂直拆分+读写分离。对应的文章分别如下:
通过上面的优化,已经能满足大部分的需求了。只有一种情况需要我们再次进行优化,那就是单表的数量急剧上升,超过了1千万以上,这个时候就要对表进行水平拆分了。
表的水平拆分是什么?
就是将一个表拆分成N个表,就像一块大石头,搬不动,然后切割成10块,这样就能搬的动了。原理是一样的。
除了能够分担数量的压力,同时也能分散读写请求的压力,当然这个得看你的分片算法了,合理的算法才能够让数据分配均匀并提升性能。
今天我们主要讲单库中进行表的拆分,也就是不分库,只分表。
既分库也分表的操作后面再讲,先来一幅图感受下未分表:

然后再来一张图感受下已分表:

从上图我们可以看出,user表由原来的一个被拆分成了4个,数据会均匀的分布在这3个表中,也就是原来的user=user0+user1+user2+user3。
分表配置
首先我们需要创建4个用户表,如下:
CREATE TABLE `user_0`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_1`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_2`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `user_3`(
id bigint(64) not null,
city varchar(20) not null,
name varchar(20) not null,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
分表的数量你需要根据你的数据量也未来几年的增长来评估。
分表的规则配置:
spring.shardingsphere.datasource.names=master
# 数据源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 分表配置
spring.shardingsphere.sharding.tables.user.actual-data-nodes=master.user_${0..3}
# inline 表达式
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
- actual-data-nodes
配置分表信息,这边用的inline表达式,翻译过来就是master.user_0,master.user_1,master.user_2,master.user_3 - inline.sharding-column
分表的字段,这边用id分表 - inline.algorithm-expression
分表算法行表达式,需符合groovy语法,上面的配置就是用id进行取模分片
如果我们有更复杂的分片需求,可以自定义分片算法来实现:
# 自定义分表算法
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.cxytiandi.sharding.algorithm.MyPreciseShardingAlgorithm
算法类:
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
for (String tableName : availableTargetNames) {
if (tableName.endsWith(shardingValue.getValue() % 4 + "")) {
return tableName;
}
}
throw new IllegalArgumentException();
}
}
在doSharding方法中你可以根据参数shardingValue做一些处理,最终返回这条数据需要分片的表名称即可。
除了单列字段分片,还支持多字段分片,大家可以自己去看文档操作一下。
需要分表的进行配置,不需要分表的无需配置,数据库操作代码一行都不用改变。
如果我们要在单库分表的基础上,再做读写分离,同样很简单,只要多配置一个从数据源就可以了,配置如下:
spring.shardingsphere.datasource.names=master,slave
# 主数据源
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456
# 从数据源
spring.shardingsphere.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8
spring.shardingsphere.datasource.slave.username=root
spring.shardingsphere.datasource.slave.password=123456
# 分表配置
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.user_${0..3}
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_${id.longValue() % 4}
# 读写分离配置
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=master
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=slave

最后
你会发现,到最后这种复杂的分表场景,用框架来解决会非常简单。至少比你自己通过字段去计算路由的表,去汇总查询这种形式要好的多。
源码参考:https://github.com/yinjihuan/sharding-jdbc
觉得不错的记得关注下哦,给个Star吧!
欢迎加入我的知识星球,一起交流技术,免费学习猿天地的课程(http://cxytiandi.com/course)
PS:目前星球中正在星主的带领下组队学习Spring Cloud,等你哦!


Sharding-JDBC:单库分表的实现的更多相关文章
- Sharding-JDBC实现水平拆分-单库分表
参考资料:猿天地 https://mp.weixin.qq.com/s/901rNhc4WhLCQ023zujRVQ 作者:尹吉欢 当单表的数量急剧上升,超过了1千万以上,这个时候就要对表进行水平 ...
- SpringBoot+Mybatis-Plus整合Sharding-JDBC5.1.1实现单库分表【全网最新】
一.前言 小编最近一直在研究关于分库分表的东西,前几天docker安装了mycat实现了分库分表,但是都在说mycat的bug很多.很多人还是倾向于shardingsphere,其实他是一个全家桶,有 ...
- mycat 单库分表
上次把mycat的读写分离搞定了,这次试下单库分表,顾名思义就是在一个库里把一个表拆分为多个 需要配置的配置文件为 schema.xml 配置内容如下 <!DOCTYPE mycat:schem ...
- springboot with appache sharding 3.1 单库分表
配置文件相关信息: #开发 server.port=7200 spring.application.name=BtspIsmpServiceOrderDev eureka.client.service ...
- Spring Boot中整合Sharding-JDBC单库分表示例
本文是Sharding-JDBC采用Spring Boot Starter方式配置第二篇,第一篇是读写分离讲解,请参考:<Spring Boot中整合Sharding-JDBC读写分离示例> ...
- mycat 单库分表实践
参考 https://blog.csdn.net/sq2006hjp/article/details/78732227 Mycat采用的水平拆分,不管是分库还是分表,都是水平拆分的.分库是指,把一个大 ...
- mycat使用之MySQL单库分表及均分数据
转载自 https://blog.csdn.net/smilefyx/article/details/72810531 1.首先在Mycat官网下载安装包,这里就以最新的1.6版本为例,下载地址为: ...
- MySQL多数据源笔记3-分库分表理论和各种中间件
一.使用中间件的好处 使用中间件对于主读写分离新增一个从数据库节点来说,可以不用修改代码,达到新增节点数据库而不影响到代码的修改.因为如果不用中间件,那么在代码中自己是先读写分离,如果新增节点, 你进 ...
- Sharding Sphere的分库分表
什么是 ShardingSphere? 1.一套开源的分布式数据库中间件解决方案 2.有三个产品:Sharding-JDBC 和 Sharding-Proxy 3.定位为关系型数据库中间件,合理在分布 ...
随机推荐
- Vue-cli脚手架 安装 并创建项目--命令
检查是否有 node - v 安装Vue-cli npm install -g vue-cli 安装好后,执行 vue list可以看到很多实用的模板,我这里实用的webpack 初始化模板 vue ...
- 监控利器-Prometheus安装与部署+实现邮箱报警
Prometheus(普罗米修斯)监控 环境准备: 三台docker主机(centos7):docker01:172.16.1.30部署服务:Prometheus server,Grafana,Nod ...
- pwn-200
题目连接 https://adworld.xctf.org.cn/media/task/attachments/49bd95c78386423997fa044a9e750015 借鉴 https:// ...
- TKinter容器frame使用
容器frame使用布局 https://www.cnblogs.com/anita-harbour/p/9315472.html TK控件使用大全 https://blog.csdn.net/rng_ ...
- 深挖计算机基础:趣谈Linux操作系统学习笔记
参考极客时间专栏<趣谈Linux操作系统>学习笔记 核心原理篇:内存管理 趣谈Linux操作系统学习笔记:第二十讲 趣谈Linux操作系统学习笔记:第二十一讲 趣谈Linux操作系统学习笔 ...
- IPv6升级测试指南(Android/iOS/Mac)
目录 我们升级到IPv6的原因 测试的时候的注意要点 Android/IOS/MAC测试总结 Android测试IPv6的方法 IOS端测试IPv6的方法 MAC浏览器端测试IPv6的方法 升级IPV ...
- jvaa之初始化块
1.初始化块的作用:对java对象进行初始化: 2.程序的执行顺序:声明成员变量的默认值-->显示初始化,多个初始化块依次被执行(同级别下按先后顺序执行)-->构造器在对成员进行赋值操作. ...
- 【朝花夕拾】Android自定义View篇之(三)Canvas绘制文字
前言 转载请声明,转自[https://www.cnblogs.com/andy-songwei/p/10968358.html],谢谢! 前面的文章中在介绍Canvas的时候,提到过后续单独讲Can ...
- spring源码分析6: ApplicationContext的初始化与BeanDefinition的搜集入库
先前几篇都是概念的讲解:回顾下 BeanDefinition 是物料 Bean是成品 BeanFactory是仓库,存储物料与成品 ApplicationContext初始化搜集物料入库,触发生产线, ...
- SpringCloud的入门学习之深入理解Eureka注册中心
1.Eureka 注册中心三种角色. 答:a.Eureka Server,注册中心,通过 Register.Get.Renew 等接口提供服务的注册和发现. b.Application Service ...