当前位置:   article > 正文

Springboot整合ShardingSphere实现分库分表,垂直拆分、水平拆分、公共表的处理_springboot sharding

springboot sharding

分库别表主要有两种解决方案:垂直拆分、水平拆分

垂直拆分

操作数据库中某张表,把这张表中一部分字段数据存到一张新表里面,再把这张表另一 部分字段数据存到另外一张表里面 例如:将商品基本信息放在一张表,商品详情放在一张表

水平拆分

将一个数据库,拆分为两个相同结构的数据库,存储数据

存储方式

方式一:按id取模方式实现,缺点:不好扩容

方式二:按id分片实现,缺点:因为id连续,热点数据可能会集中到一个数据库

其他思路:大范围按时间分,小范围取模分

分库分表可能出现的问题:

事务一致性问题:单表操作事务执行失败可以回滚,分表之后可能会插入到多条数据库

跨节点关联查询:当查询固定范围的数据也在多个数据库中

主键避重问题:数据库表主键冲突

所以在开发中:数据增加不要立马做水平拆分,首先考虑缓存处理,读写分离,使用索引等

ShardingSphere

开源分布式数据库中间件解决方案,主要有Sharding-JDBC和Sharding-Proxy

客户端分库分表:以jar包形式放在java应用里,通过Sharding-JDBC去找对应数据,主要作用数据分片,读写分离

服务端分库分表:利用Sharding-Proxy伪装成数据库,分库分表由Sharding-Proxy实现

Sharding-JDBC实现水平分表

创建数据库,按水平分表方式

在数据库创建两张表 course_1 和 course_2

约定规则:如果添加课程 id 是偶数把数据添加 course_1,如果奇数添加到 course_2

创建springboot项目,添加依赖

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter</artifactId>
  4. </dependency>
  5. <dependency>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-test</artifactId>
  8. </dependency>
  9. <dependency>
  10. <groupId>com.alibaba</groupId>
  11. <artifactId>druid-spring-boot-starter</artifactId>
  12. <version>1.1.20</version>
  13. </dependency>
  14. <dependency>
  15. <groupId>mysql</groupId>
  16. <artifactId>mysql-connector-java</artifactId>
  17. </dependency>
  18. <dependency>
  19. <groupId>org.apache.shardingsphere</groupId>
  20. <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
  21. <version>4.0.0-RC1</version>
  22. </dependency>
  23. <dependency>
  24. <groupId>com.baomidou</groupId>
  25. <artifactId>mybatis-plus-boot-starter</artifactId>
  26. <version>3.0.5</version>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.projectlombok</groupId>
  30. <artifactId>lombok</artifactId>
  31. </dependency>

实体类

  1. @Data
  2. public class Course {
  3. private Long cid;
  4. private String cname;
  5. private Long userId;
  6. private String cstatus;
  7. }

mapper层

  1. @Repository
  2. public interface CourseMapper extends BaseMapper<Course> {
  3. }

启动类加注解

@MapperScan("com.lzq.mapper")

配置 Sharding-JDBC 分片策略

在配置文件中配置

  1. # shardingjdbc 分片策略
  2. # 配置数据源,给数据源起名称
  3. spring.shardingsphere.datasource.names=m1
  4. # 一个实体类对应两张表,覆盖
  5. spring.main.allow-bean-definition-overriding=true
  6. #配置数据源具体内容,包含连接池,驱动,地址,用户名和密码
  7. spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
  8. spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
  9. spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/sharding?serverTimezone=GMT%2B8
  10. spring.shardingsphere.datasource.m1.username=root
  11. spring.shardingsphere.datasource.m1.password=root
  12. #指定 course 表分布情况,配置表在哪个数据库里面,表名称都是什么 m1.course_1 ,m1.course_2
  13. spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_$->{1..2}
  14. # 指定 course 表里面主键 cid 生成策略 SNOWFLAKE 雪花算法
  15. spring.shardingsphere.sharding.tables.course.key-generator.column=cid
  16. spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
  17. # 指定分片策略 约定 cid 值偶数添加到 course_1 表,如果 cid 是奇数添加到 course_2
  18. spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
  19. spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2 + 1}
  20. # 打开 sql 输出日志
  21. spring.shardingsphere.props.sql.show=true

测试

  1. @SpringBootTest
  2. class ShardingJdbcApplicationTests {
  3. @Autowired
  4. private CourseMapper courseMapper;
  5. @Test
  6. void add() {
  7. Course course = new Course();
  8. course.setCname("java");
  9. course.setUserId(10l);
  10. course.setCstatus("normal");
  11. courseMapper.insert(course);
  12. }
  13. @Test
  14. public void find(){
  15. QueryWrapper<Course> wrapper = new QueryWrapper<>();
  16. wrapper.eq("cid",714887289653690369l);
  17. Course course = courseMapper.selectOne(wrapper);
  18. System.out.println(course);
  19. }
  20. }

springboot版本不同可能会报错,由于一个实体类对应两个数据库,在配置文件添加

spring.main.allow-bean-definition-overriding=true

水平分库

创建两个数据库,每个数据库里创建两个表分别为course_1 和 course_2

约定分片规则:userid为偶数加入第一个数据库,cid为偶数放入course_1表

修改之前代码:配置分片规则,在配置文件中加入

  1. # 配置数据源,给数据源起名称,
  2. # 水平分库,配置两个数据源
  3. spring.shardingsphere.datasource.names=m1,m2
  4. # 一个实体类对应两张表,覆盖
  5. spring.main.allow-bean-definition-overriding=true
  6. #配置第一个数据源具体内容,包含连接池,驱动,地址,用户名和密码
  7. spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
  8. spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
  9. spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?serverTimezone=GMT%2B8
  10. spring.shardingsphere.datasource.m1.username=root
  11. spring.shardingsphere.datasource.m1.password=root
  12. #配置第二个数据源具体内容,包含连接池,驱动,地址,用户名和密码
  13. spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
  14. spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.cj.jdbc.Driver
  15. spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?serverTimezone=GMT%2B8
  16. spring.shardingsphere.datasource.m2.username=root
  17. spring.shardingsphere.datasource.m2.password=root
  18. #指定数据库分布情况,数据库里面表分布情况
  19. # m1 m2 course_1 course_2
  20. spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{1..2}.course_$->{1..2}
  21. # 指定 course 表里面主键 cid 生成策略 SNOWFLAKE
  22. spring.shardingsphere.sharding.tables.course.key-generator.column=cid
  23. spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
  24. # 指定表分片策略 约定 cid 值偶数添加到 course_1 表,如果 cid 是奇数添加到course_2
  25. spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding.column=cid
  26. spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm.expression=course_$->{cid % 2 + 1}
  27. # 指定数据库分片策略 约定 user_id 是偶数添加 m1,是奇数添加 m2
  28. #spring.shardingsphere.sharding.default-database-strategy.inline.sharding.column=user_id
  29. #spring.shardingsphere.sharding.default-database-strategy.inline.algorithm.expression=m$->{user_id % 2 + 1}
  30. #写法二 对具体表有固定规则
  31. spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
  32. spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{user_id % 2 + 1}

测试同上

垂直分库

专库专用,查询用户信息时去用户数据库查用户表

创建数据库user_db,创建用户信息表t_user

创建实体类与mapper

  1. @Data
  2. @TableName(value = "t_user") //指定对应表
  3. public class User {
  4. private Long userId;
  5. private String username;
  6. private String ustatus;
  7. }
  8. @Repository
  9. public interface UserMapper extends BaseMapper<User> {
  10. }

配置文件添加

  1. # 配置数据源,给数据源起名称
  2. spring.shardingsphere.datasource.names=m1,m2,m0
  3. .....
  4. #配置第三个数据源具体内容,包含连接池,驱动,地址,用户名和密码
  5. spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
  6. spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
  7. spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT%2B8
  8. spring.shardingsphere.datasource.m0.username=root
  9. spring.shardingsphere.datasource.m0.password=root
  10. # 配置 user_db 数据库里面 t_user 专库专表
  11. spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m$->{0}.t_user
  12. # 指定 course 表里面主键 cid 生成策略 SNOWFLAKE
  13. spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
  14. spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE

公共表

存储固定数据,很少发生变化,查询时需要进行关联,例如用户的状态表,字典等

在多个数据需中都创建相同结构的表

在配置文件中添加

  1. # 配置公共表
  2. spring.shardingsphere.sharding.broadcast-tables=t_udict
  3. spring.shardingsphere.sharding.tables.t_udict.key-generator.column=dictid
  4. spring.shardingsphere.sharding.tables.t_udict.key-generator.type=SNOWFLAKE

当有修改操作时,会向多个数据库中t_udict表进行修改

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/210883
推荐阅读
相关标签
  

闽ICP备14008679号