Sharding——JDBC
它定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。
对比图:
开发人员只需正常写查询、mapper即可、无感知。
分库分表概念
随着业务的不断增长,数据也飞速增长,访问也随之变慢,添加从库、新建索引等很多操作仍严重下降,分库分表需求迫在眉睫。
方案一:
通过提升服务性能来提升数据处理能力,例如:扩容、CPU等,但成本很高。
方案二:
把数据分散在不同数据集中,大表拆成小表、数据落盘到不同库中,从而使得数据集变小从而提升性能。
-
垂直分库
以表
为依据,按照业务需求将表
拆到不同库中。
每个库
的结构不一样。
每个库
的数据不一样,没有交集。
所有库的并集
是全量数据。
场景:
这一步拆分基本是服务化,例如,中间表、字典表、配置表等越来越多,可以将这些表拆分到单独库中,甚至可以微服务化。
-
垂直分表
以字段
为依据,按照字段活跃性拆到不同表
中。
每张表结构
不一样。
每张表数据也
不一样,至少有一列交集
用于关联。
所有表并集
数据是全量数据。
场景:
用户表中有id、名称、住址等信息,每次查询用户信息时住址字段使次数很低,大字段等单独拆分一张,从而减少IO提升性能。
-
水平分库
以字段
为依据,按照一定策略(hash、range等),将一个库
中的数据拆分到多个库
中。
每个库结构
都一样。
每个库数据
都不一样,没有交集。
所有库并集
是全量数据。
场景:
库多了,IO和CPU压力可以成倍缓解。
-
水平分表
以字段
为依据,按照一定策略(hash、range等),将一个表
中的数据拆分到多个表
中。
每张表结构
都一样。
每张表数据
都不一样,没有交集。
所有表并集
是全量数据。
场景:
表的数据量少了,SQL执行效率高,IO和CPU压力可以成倍缓解。
POM文件
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.3.2</version>
</dependency>
<!-- Druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- 分库分表 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
分表配置
新建数据库名:sharding
新建表名:tbl_dept_1和tbl_dept_2
表结构:
说明:根据dept_id进行分表
选择。
yml文件:
spring:
main:
allow-bean-definition-overriding: true
# 配置Sharding-JDBC的分片策略
shardingsphere:
# 配置数据源,给数据源起名g1,g2...此处可配置多数据源
datasource:
names: g1
g1:
type: "com.alibaba.druid.pool.DruidDataSource"
driver-class-name: "com.mysql.cj.jdbc.Driver"
url: "jdbc:mysql://localhost:3306/sharding?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
username: "账号"
password: "密码"
# 配置表的分布,表的策略
sharding:
tables:
# 表名
tbl_dept:
actual-data-nodes: g1.tbl_dept_${0..1}
key-generator:
# 指定tbl_dept表 主键dept_id 生成策略为 SNOWFLAKE
column: dept_id
type: SNOWFLAKE
table-strategy:
inline:
# 指定分片策略 约定dept_id值是偶数添加到tbl_dept_1表,如果dept_id奇数添加到tbl_dept_2表
sharding-column: dept_id
algorithm-expression: tbl_dept_${dept_id % 2 + 1}
# 打开sql输出日志
props:
sql:
show: true
执行查询或插入代码:
TblDept byId = tblDeptService.getById(6);
执行效果日志:
分库配置
新建数据库名:sharding_1,sharding_2
在两个库中分别新建表名:tbl_dept_1和tbl_dept_2
表结构:
说明:根据s_id进行分库
选择,根据dept_id进行分表
选择。
yml文件:
spring:
main:
allow-bean-definition-overriding: true
# 配置Sharding-JDBC的分片策略
shardingsphere:
# 配置数据源,给数据源起名g1,g2...此处可配置多数据源
datasource:
names: g1,g2
g1:
type: "com.alibaba.druid.pool.DruidDataSource"
driver-class-name: "com.mysql.cj.jdbc.Driver"
url: "jdbc:mysql://localhost:3306/sharding_1?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
username: "账号"
password: "密码"
g2:
type: "com.alibaba.druid.pool.DruidDataSource"
driver-class-name: "com.mysql.cj.jdbc.Driver"
url: "jdbc:mysql://localhost:3306/sharding_2?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
username: "账号"
password: "密码"
# 配置表的分布,表的策略
sharding:
tables:
# 表名
tbl_dept:
actual-data-nodes: g${1..2}.tbl_dept_${1..2}
# 指定tbl_dept表 主键dept_id 生成策略为 SNOWFLAKE
key-generator:
column: dept_id
type: SNOWFLAKE
# 指定分片策略 约定dept_id值是偶数添加到tbl_dept_1表,如果dept_id奇数添加到tbl_dept_2表
database-strategy:
inline:
sharding-column: s_id
algorithm-expression: g${s_id % 2 + 1}
table-strategy:
inline:
sharding-column: dept_id
algorithm-expression: tbl_dept_${dept_id % 2 + 1}
# 打开sql输出日志
props:
sql:
show: true
执行查询或插入代码:
TblDept tblDept = new TblDept();
tblDept.setDeptId(16L);
tblDept.setDeptName("分库");
tblDept.setSId(6);
tblDeptService.save(tblDept);
执行效果日志:
执行查询或插入代码:
TblDept tblDept = new TblDept();
tblDept.setDeptId(19L);
tblDept.setDeptName("分库");
tblDept.setSId(6);
tblDeptService.save(tblDept);
执行效果日志:
转自:https://blog.csdn.net/s1078229131/article/details/106785894