剧情回顾

前面,我们一共学习了读写分离,垂直拆分,垂直拆分+读写分离。对应的文章分别如下:

Sharding-JDBC:查询量大如何优化?

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:单库分表的实现的更多相关文章

  1. Sharding-JDBC实现水平拆分-单库分表

    参考资料:猿天地   https://mp.weixin.qq.com/s/901rNhc4WhLCQ023zujRVQ 作者:尹吉欢 当单表的数量急剧上升,超过了1千万以上,这个时候就要对表进行水平 ...

  2. SpringBoot+Mybatis-Plus整合Sharding-JDBC5.1.1实现单库分表【全网最新】

    一.前言 小编最近一直在研究关于分库分表的东西,前几天docker安装了mycat实现了分库分表,但是都在说mycat的bug很多.很多人还是倾向于shardingsphere,其实他是一个全家桶,有 ...

  3. mycat 单库分表

    上次把mycat的读写分离搞定了,这次试下单库分表,顾名思义就是在一个库里把一个表拆分为多个 需要配置的配置文件为 schema.xml 配置内容如下 <!DOCTYPE mycat:schem ...

  4. springboot with appache sharding 3.1 单库分表

    配置文件相关信息: #开发 server.port=7200 spring.application.name=BtspIsmpServiceOrderDev eureka.client.service ...

  5. Spring Boot中整合Sharding-JDBC单库分表示例

    本文是Sharding-JDBC采用Spring Boot Starter方式配置第二篇,第一篇是读写分离讲解,请参考:<Spring Boot中整合Sharding-JDBC读写分离示例> ...

  6. mycat 单库分表实践

    参考 https://blog.csdn.net/sq2006hjp/article/details/78732227 Mycat采用的水平拆分,不管是分库还是分表,都是水平拆分的.分库是指,把一个大 ...

  7. mycat使用之MySQL单库分表及均分数据

    转载自 https://blog.csdn.net/smilefyx/article/details/72810531 1.首先在Mycat官网下载安装包,这里就以最新的1.6版本为例,下载地址为:  ...

  8. MySQL多数据源笔记3-分库分表理论和各种中间件

    一.使用中间件的好处 使用中间件对于主读写分离新增一个从数据库节点来说,可以不用修改代码,达到新增节点数据库而不影响到代码的修改.因为如果不用中间件,那么在代码中自己是先读写分离,如果新增节点, 你进 ...

  9. Sharding Sphere的分库分表

    什么是 ShardingSphere? 1.一套开源的分布式数据库中间件解决方案 2.有三个产品:Sharding-JDBC 和 Sharding-Proxy 3.定位为关系型数据库中间件,合理在分布 ...

随机推荐

  1. C#&.Net干货分享- 构建Spire-Office相关Helper操作Word、Excel、PDF等

    先下载好如下的组件: 直接使用完整源码分享: namespace Frame.Office{    /// <summary>    /// Spire_WordHelper    /// ...

  2. 阿里云ECS服务器部署HADOOP集群(五):Pig 安装

    本篇将在阿里云ECS服务器部署HADOOP集群(一):Hadoop完全分布式集群环境搭建的基础上搭建. 1 环境介绍 一台阿里云ECS服务器:master 操作系统:CentOS 7.3 Hadoop ...

  3. Java之Collection接口(单列集合根接口)

    集合概述 集合到底是什么呢?集合:集合是java中提供的一种容器,可以用来存储多个数据 集合和数组既然都是容器,它们有啥区别呢? 区别1: 数组的长度是固定的. 集合的长度是可变的. 区别2:  数组 ...

  4. go语言之if语句和switch语句和循环语句

    1.if语句 package main import ( "fmt" "io/ioutil" ) func main() { //流程控制 //使用常量定义一个 ...

  5. ABP之Logging

    服务器端 ABP使用Castle Windsor的日志设施.它可以使用不同的日志库:Log4Net.NLog.Serilog等等.Castle为所有日志程序库提供了一个公共接口,这样,我们可以独立的使 ...

  6. 【C++常用函数】头文件<algorithm>中的常用函数(绝对值,交换,比较)

    swap(a,b) 用于交换a,b两个变量的值: max(a,b) 返回a,b中的最大值: min(a,b) 返回a,b中的最小值: abs(x) 返回x的绝对值,x必须是整数:

  7. SpringBoot启动项目时提示:Error:java: 读取***.jar时出错;

    场景 在IDEA中新建SpringBoot项目后,修改了默认的Maven仓库和配置文件,然后在启动项目时提示: Error:java: 读取\org\assertj\assertj-core\3.11 ...

  8. CSS 让div,span等块级、非快级元素排列在同一行

    让div,span等块级.非快级元素排列在同一行 by:授客 QQ:1033553122 例子:让两个div排列在同一行 给div添加float样式 <!DOCTYPE html> < ...

  9. Mac进行Flutter的相关开发配置

    参考链接:https://www.cnblogs.com/tangtianming/p/10797227.html

  10. ios中设置UIButton圆角,添加边框

    //例如: UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(50, ...