Administrator
Published on 2023-08-29 / 40 Visits
0

基于shardingJDBC的分库分表

一、分库分表有哪些方式

1. 垂直分库分表

垂直分库:按照业务模块的不同,将表拆分到不同的数据库中,适合业务之间的耦合度非常低、业务逻辑清晰的系统。

  • 降低业务中的耦合,方便对不同的业务进行分级管理+可以提升IO、数据库连接数、解决单机硬件存储资源的瓶颈问题

垂直分表:将一个表按照字段分成多个表,每个表存储其中一部分字段。一般会将常用的字段放到一个表中,将不常用的字段放到另一个表中。

  • (1)避免IO竞争减少锁表的概率。因为大的字段效率更低,第一,大字段占用的空间更大,单页内存储的行数变少,会使得IO操作增多;第二数据量大,需要的读取时间长。

  • (2)可以更好地提升热门数据的查询效率。

垂直拆分的缺点:

  • 主键出现冗余,需要管理冗余列

  • 事务的处理变得复杂

  • 仍然存在单表数据量过大的问题

2. 水平分库分表

水平分库:把同一个表的数据按照一定规则拆分到不同的数据库中,不同的数据库可以放到不同的服务器上。

  • 解决了单库大数据量的瓶颈问题

  • IO冲突减少,锁的竞争减少,某个数据库出现问题不影响其他数据库,提高了系统的稳定性和可用性

水平分表:在同一个数据库内,把同一个表的数据按照一定规则拆分到多个表中。

  • 解决了单表数据量过大的问题

  • 避免IO竞争并减少锁表的概率

水平拆分的缺点:

  • 分片事务一致性难以解决

  • 跨节点JOIN性能差,逻辑会变得复杂

  • 数据扩展难度大,不易维护

二、基于shardingJDBC的水平分表实现

  1. 导入相关jar包

		<dependency>
			<groupId>org.apache.shardingsphere</groupId>
			<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
			<version>4.1.1</version>
		</dependency>

  1. 相关springboot配置

spring:
  shardingsphere:
    props:
      sql.show: true
    datasource:
      names: ds0,ds1,ds2
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://23.13.6.65:3307/sharding_1?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSl=false&useUnicode=true
        username: root
        password: Mysql@123456
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://23.13.6.65:3307/sharding_2?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSl=false&useUnicode=true
        username: root
        password: Mysql@123456
      ds2:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://23.13.6.65:3307/sharding_3?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSl=false&useUnicode=true
        username: root
        password: Mysql@123456

    sharding:
      tables:
        # 需要水平拆分的逻辑表名
        test:
          # 需要水平拆分的物理数据库名和物理表名
          actual-data-nodes: ds$->{0..1}.test_$->{0..1}
          # 水平分表的设置
          table-strategy:
            standard:
              sharding-column: id
              precise-algorithm-class-name: com.example.shardingjdbc.custom.CustomTables
          # 水平分库的设置
          database-strategy:
            standard:
              sharding-column: age
              precise-algorithm-class-name: com.example.shardingjdbc.custom.CustomDatabase
          # 雪花算法
          key-generator:
            column: id
            type: SNOWFLAKE
            props:
              worker-id: 1

#    sharding:
#      tables:
#        test:
#          actual-data-nodes: ds$->{0..1}.test_$->{0..1}
#          database-strategy:
#            inline:
#              sharding-column: id
#              algorithm-expression: ds$->{id % 2}
#          table-strategy:
#            inline:
#              sharding-column: id
#              algorithm-expression: test_$->{id % 2}
#          key-generator:
#            column: id
#            type: SNOWFLAKE
#            props:
#              worker-id: 1