UUID
uuid是生成32位长的字符串,一般作为ID ,不建议使用 字符串作为主键
SNOWFLAKE 雪花算法 配置
sharding-jdbc 可设置 最大容忍的时钟回拨毫秒数 , 超过这个时间就报错
1. 首先指定数据库中的哪个字段为主键
spring.shardingsphere.sharding.tables.shard.key-generator.column=id
2. 指定主键的生成策略
spring.shardingsphere.sharding.tables.shard.key-generator.type=SNOWFLAKE
3. 指定 工作机器数量 最大是2的10次方 , 即小于 1024 就可以
spring.shardingsphere.sharding.tables.shard.key-generator.props.worker.id=1000
4. 雪花算法依据时间戳来生成的,一旦时间戳回拨就会造成 id 重复的可能
# 最大容忍的时钟回拨毫秒数 spring.shardingsphere.sharding.tables.shard.key-generator.max.tolerate.time.difference.milliseconds=5
数据库表结构如下:
有两个数据库,分别是 test1、test2数据库,每个库里分别有shard_0、shard_1、shard_2 3张表。
CREATE TABLE `shard_0` (
`id` bigint(20) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`user_id` bigint(20) DEFAULT NULL,
`remark` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
appliaction.properties
server.port=8088
#[-----------------------------------------------------------雪花算法 配置-----------------------------------------------------------------]
# 【配置真实数据源】
spring.shardingsphere.datasource.names=ds0,ds1
# 【配置第 1 个数据源】
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost/test1?characterEncoding=utf-8&serverTimezone=UTC
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# 【配置第 2 个数据源】
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf-8&serverTimezone=UTC
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 【配置分库策略】
## shard 数据库分片键 : user_id
spring.shardingsphere.sharding.tables.shard.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.shard.database-strategy.inline.algorithm-expression=ds$->{user_id % 2}
# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 【配置分表策略】
spring.shardingsphere.sharding.tables.shard.actual-data-nodes=ds$->{0..1}.shard_$->{0..2}
spring.shardingsphere.sharding.tables.shard.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.shard.table-strategy.inline.algorithm-expression=shard_$->{id % 3}
# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 【指定ID生成策略】
spring.shardingsphere.sharding.tables.shard.key-generator.column=id
spring.shardingsphere.sharding.tables.shard.key-generator.type=SNOWFLAKE
#小于 1024 即可
spring.shardingsphere.sharding.tables.shard.key-generator.props.worker.id=1000
# 最大容忍的时钟回拨毫秒数
spring.shardingsphere.sharding.tables.shard.key-generator.props.max.tolerate.time.difference.milliseconds=5
Spring 测试代码
@Test
public void shardInsert(){
Shard shard = new Shard();
shard.setName("67");
shard.setUserId(23L);
shard.setRemark("87saf");
int result = shardMapper.save(shard);
System.err.println("插入结果 : "+ result);
}
⭐⭐⭐
【shard 表的主键是 id ,但是在插入的时候不需要设定 id 的值, sharding会自动生成】
【同时sql 中也不需要 插入id 字段】
public class Shard implements Serializable {
private Long id;
private String name;
private Long userId;
private String remark;
【同时sql 中也不需要 插入id 字段】
<insert id="save">
insert into shard ( `name`, user_id, remark)
values ( #{name,jdbcType=VARCHAR},
#{userId,jdbcType=BIGINT},
#{remark,jdbcType=VARCHAR})
</insert>
自定义分片策略
自定义分片策略,配置需要改动。同样,
1. 也是需要先定义哪个字段来分片,
2. 然后使用自定义的分片策略,把全路径赋值过来
application.properties 中更改的部分就是这一块
# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 【配置分表策略】
spring.shardingsphere.sharding.tables.shard.actual-data-nodes=ds$->{0..1}.shard_$->{0..2}
# 这是老的方式
#spring.shardingsphere.sharding.tables.shard.table-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.tables.shard.table-strategy.inline.algorithm-expression=shard_$->{id % 3}
# 这是自定义分片策略
spring.shardingsphere.sharding.tables.shard.table-strategy.standard.sharding-column=id
# precise-algorithm-class-name:精准表达式类名 用于等于 in 这种语句中; range-algorithm-class-name:范围,用于 between
spring.shardingsphere.sharding.tables.shard.table-strategy.standard.precise-algorithm-class-name=com.example.shardingjdbc.sharding.MySharding
这是自定义的 分片策略
package com.example.shardingjdbc.sharding;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.springframework.stereotype.Component;
import java.util.Collection;
@Component
public class MySharding implements PreciseShardingAlgorithm<Long> {
// <Long> 是因为 id 是 long 类型
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
Long id = (Long) preciseShardingValue.getValue();
// 如果 id 是 string ,可以 id.hashcode()
int model = (int) (id % collection.size());
model = Math.abs(model); // 取绝对值
System.err.println("collection.size() : "+collection.size());
System.err.println("model : "+model);
String[] strings = collection.toArray(new String[0]);
System.err.println(strings[0] +" " + strings[1]+" " + strings[2]);
return strings[model];
}
}
=======================================
console打印结果 :
collection.size() : 3 collection 这里就是所有表的集合,一个库是3张表,所有是3
model : 2
shard_0 shard_1 shard_2