记录如下:
项目中采用的分表中间件为shardingjdbc
常见的分片算法非常多:
取模分片算法,根据分片容量的范围分片算法,根据分片边界的范围分片算法,根据时间范围分片算法,自定义类分片算法 等等..
需求不同,采用的策略也不同,这里我使用的是自定义类分片算法,一般单表行数超过500万行或者单标容量超过2GB,才推荐进行分库分表。
进入主题..
1.导入shardingjdbc依赖
<!--分库分表中间件-->
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>3.1.0</version>
</dependency>
2.撰写properties或者yml配置,我这里用的yml 看起来简洁一点
spring:
main:
allow-bean-definition-overriding: true
server:
port: 8701
#按照范围分片
sharding:
jdbc:
datasource:
names: database
database:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/database?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8&tinyInt1isBit=false
username: root
password: 123456
# 水平拆分的数据库(表) 配置分库 + 分表策略 行表达式分片策略
config:
sharding:
tables:
t_order: #逻辑表名 (需要分的表)
# 数据节点:数据源$->{0..N}.逻辑表名$->{0..N}
actual-data-nodes: database.t_order$->{1..5}
# 拆分表策略,也就是什么样子的数据放入放到哪个数据表中。
table-strategy:
standard:
precise-algorithm-class-name: com.efuav.jdbcdemo.config.UavPreciseShardingAlgorithm
sharding-column: city # 分片字段(分片键)
# sharding-algorithm-name: table-inline #分片算法名称
# #分片算法
# sharding-algorithms:
# table-inline: #分片算法名称
# type: VOLUME_RANGE # 分片算法配置:基于分片容量的范围分片
# props:
# sharding-volume: !!str 2 # 表示一个表中最多2个数据
# range-lower: !!str 1
# range-upper: !!str 40
# 打印执行的数据库
props:
sql:
show: true
开启sql打印,查看你的实际sql走向
3.自定义配置类
package com.efuav.jdbcdemo.config;
import io.shardingsphere.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.api.algorithm.sharding.standard.PreciseShardingAlgorithm;
import lombok.extern.slf4j.Slf4j;
import java.util.Collection;
//分表规则
@Slf4j
public class UavPreciseShardingAlgorithm implements PreciseShardingAlgorithm<String> {
/**
* 插入数据 改写表的名称
* 查询 改写表的名称
*
* @param collection
* @param preciseShardingValue
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
// UAV07JDE6E0020240
String value = preciseShardingValue.getValue();
int las = value.charAt(value.length() - 1);
String tableName = "t_order" + ((las % 4)+1);
log.info("<tableName{}>", tableName);
return tableName;
}
}
自定义分片类,相当于是指定数据前往那个表名,重写doSharding方法,按你的需求去写,我这是用city字段去分了5个表,取字符串最后一个字符跟4取模,依次分为了5个表。
debug
可以看到通过doSharding,collection里面是我要求分的5张表,preciseShardingValue是分表的字段,按照我的定义的规则自动计算出表名为order1,去操作这个表。
doSharding里面的PreciseShardingValue的泛性可以按你要求改,比如你要用类似什么user_id 分,就PreciseShardingValue<Long>,PreciseShardingValue这个字段里面就是你的分表字段,然后按你的需求写代码就好了,想怎么分都可以。(不要照搬过去就开始跑=-=)
4.最后发一下这个demo的sql 想测试的自己试一试
/*
Navicat MySQL Data Transfer
Source Server : ikun
Source Server Type : MySQL
Source Server Version : 80029
Source Host : localhost:3306
Source Schema : database
Target Server Type : MySQL
Target Server Version : 80029
File Encoding : 65001
Date: 03/03/2023 11:02:45
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_order0
-- ----------------------------
DROP TABLE IF EXISTS `t_order0`;
CREATE TABLE `t_order0` (
`order_id` bigint(0) NOT NULL AUTO_INCREMENT,
`user_id` bigint(0) NULL DEFAULT NULL,
`order_price` decimal(10, 2) NULL DEFAULT NULL,
`city` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
SET FOREIGN_KEY_CHECKS = 1;
5.总结:shardingjdbc就是通过算法去修改表名,执行你的sql操作
记录问题....