之前已经搭建好了基本的项目结构,下面开始数据库水平的切分,ShardingSphereJDBC是一个分表分库整合工具,他只帮你完成在分表分库之后的数据整理汇总等工作,不能帮你进行分表分库,比如你已经有数据库了想通过ShardingSphereJDBC进行分库是不行的。不过最新的4.1.0版本的ShardingSphere提出了ShardingSphere-Scaling用于做数据库分片迁移,目前处于alpha开发阶段,未来应该会有更方便的数据库切分解决方案。
单库水平切分
# 单库水平切分
spring:
shardingsphere:
# 所有数据库的别名
datasource:
names: ss1
# 具体数据库的配置信息
ss1:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/ss1?serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: admin
# 分表分库策略
sharding:
# 需要分表的策略
tables:
# 表名前缀 采坑这里必须是user 不能是user_ user_会报找不到表切分失败
user:
# 这里写实际的表明 比如 表 user_0 和 user_1 则user_$->{0..1} 或者user_$->{0..1..2}
actual-data-nodes: ss1.user_$->{0..1}
# 主键生成规则 默认使用雪花算法
key-generator:
column: id
type: SNOWFLAKE
# 分表策略
table-strategy:
inline:
# 数据表达式计算 这里是为 id % 2 ==0 就是user_0 如果 id % 2==1 则user_id
algorithm-expression: user_$->{id % 2}
sharding-column: id
props:
sql:
# 打印实际生成SQL
show: true
main:
allow-bean-definition-overriding: true
@RunWith(SpringRunner.class)
@SpringBootTest
public class SingleDataBaseHorizontalTest {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert() {
IntStream.range(0, 10).forEach(i -> {
User user = new User();
user.setName("name" + i);
user.setAge(10 + i);
userMapper.insert(user);
});
}
@Test
public void testFind(){
userMapper.selectList(null).forEach(System.out::println);
}
@Test
public void testFindByCondition(){
userMapper.selectList(Wrappers.lambdaQuery(User.class).ge(User::getAge,15)).forEach(System.out::println);
}
}
user_0表中所有的id都是偶数,反之user_1的id都是奇数,此时已经实现了对单数据库的水平切分
多库的水平切分
# 单库水平切分
spring:
shardingsphere:
# 所有数据库的别名
datasource:
# 配置多个数据源
names: ss1,ss2
# 具体数据库的配置信息
ss1:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/ss1?serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: admin
ss2:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/ss2?serverTimezone=Asia/Shanghai
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: admin
# 分表分库策略
sharding:
# 需要分表的策略
tables:
# 表名前缀
user:
actual-data-nodes: ss$->{1..2}.user_$->{0..1}
# 主键生成规则 默认使用雪花算法
key-generator:
column: id
type: SNOWFLAKE
# 分库策略 与分表策略配置类似
database-strategy:
inline:
shardingColumn: id
algorithmExpression: ss${id % 2 + 1}
# 分表策略
table-strategy:
inline:
# 数据表达式计算 这里是为 id % 2 ==0 就是user_0 如果 id % 2==1 则user_1
algorithm-expression: user_$->{id % 2}
sharding-column: id
props:
# 实际生成SQL
sql:
show: true
main:
allow-bean-definition-overriding: true
@RunWith(SpringRunner.class)
@ActiveProfiles("multipleDatasourceHorizaontal")
@SpringBootTest
public class MultipleDataBaseHorizontalTest {
@Autowired
private UserMapper userMapper;
@Test
public void testInsert() {
IntStream.range(0, 10).forEach(i -> {
User user = new User();
user.setName("name" + i);
user.setAge(10 + i);
userMapper.insert(user);
});
}
@Test
public void testFind(){
userMapper.selectList(null).forEach(System.out::println);
}
@Test
public void testFindByCondition(){
userMapper.selectList(Wrappers.lambdaQuery(User.class).ge(User::getAge,15)).forEach(System.out::println);
}
}
运行测试发现所有偶数id的数据都会加在ss1数据库中的user_0表中
所有奇数id的数据会保存在ss2表中的user_1表中