You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot项目实现水平分库分表及一对多关系适配问题

Spring Boot + Spring Data JPA 实现水平分库分表方案

一、核心选型:用Sharding-JDBC做分库分表

Spring Boot默认仅支持单数据源,但可以通过Sharding-JDBC(ShardingSphere生态成员)实现JDBC层的分库分表。它对Spring Data JPA友好,无需大幅修改现有业务代码,属于轻量级、侵入性低的解决方案。

二、集成步骤

1. 引入依赖

在pom.xml中添加ShardingSphere的Spring Boot starter及MySQL驱动依赖:

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.4.1</version> <!-- 建议使用最新稳定版 -->
</dependency>
<dependency>
    <groupId>com.mysql.cj</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

2. 配置分库分表规则

以用户订单场景为例(按user_id分库,order_id分表),在application.yml中配置数据源、分片策略:

spring:
  shardingsphere:
    datasource:
      names: ds0,ds1 # 定义两个分库实例
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/db0?useSSL=false&serverTimezone=UTC
        username: root
        password: root
      ds1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/db1?useSSL=false&serverTimezone=UTC
        username: root
        password: root
    rules:
      sharding:
        tables:
          t_order: # 逻辑表名,对应多个物理表
            actual-data-nodes: ds$->{0..1}.t_order_$->{0..1} # 物理表集合:ds0.t_order_0/1、ds1.t_order_0/1
            database-strategy:
              standard:
                sharding-column: user_id
                sharding-algorithm-name: user-inline # 分库算法
            table-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: order-inline # 分表算法
        sharding-algorithms:
          user-inline:
            type: INLINE
            props:
              algorithm-expression: ds$->{user_id % 2} # 按user_id取模分库
          order-inline:
            type: INLINE
            props:
              algorithm-expression: t_order_$->{order_id % 2} # 按order_id取模分表
    props:
      sql-show: true # 打印路由后的SQL,方便调试

3. 调整JPA配置

  • 禁用JPA自动建表(物理表需提前创建,或开启ShardingSphere的自动建表功能):
spring:
  jpa:
    hibernate:
      ddl-auto: none
  • 实体类仅需指定逻辑表名,无需关联具体物理表:
@Entity
@Table(name = "t_order")
public class Order {
    @Id
    private Long orderId;
    private Long userId;
    // 其他字段、getter/setter
}

4. 验证逻辑

直接使用Spring Data JPA的Repository操作数据,Sharding-JDBC会自动完成路由。比如插入userId=1的订单,会被路由到ds1;orderId=3的订单会被路由到t_order_1。

三、一对多关联场景的分库分表处理

假设有t_order(订单)和t_order_item(订单明细)的一对多关系,核心原则是关联表使用相同的分片键,保证数据落在同一个分片,避免跨库跨表关联的性能损耗。

1. 分片策略统一

  • 让t_order_item复用t_order的分片规则:以user_id分库,order_id分表,确保同一订单的主表和明细数据落在同一个库和表中。
  • 配置示例:
spring:
  shardingsphere:
    rules:
      sharding:
        tables:
          t_order_item:
            actual-data-nodes: ds$->{0..1}.t_order_item_$->{0..1}
            database-strategy:
              standard:
                sharding-column: user_id
                sharding-algorithm-name: user-inline
            table-strategy:
              standard:
                sharding-column: order_id
                sharding-algorithm-name: order-inline

2. JPA关联查询适配

在实体类中正常使用@OneToMany/@ManyToOne关联,只要分片键一致,Sharding-JDBC会自动路由到对应分片完成关联:

@Entity
@Table(name = "t_order")
public class Order {
    @Id
    private Long orderId;
    private Long userId;
    
    @OneToMany(mappedBy = "order", fetch = FetchType.LAZY)
    private List<OrderItem> items;
    // ...
}

@Entity
@Table(name = "t_order_item")
public class OrderItem {
    @Id
    private Long itemId;
    private Long orderId;
    private Long userId; // 冗余user_id用于分库路由
    
    @ManyToOne
    @JoinColumn(name = "order_id")
    private Order order;
    // ...
}

3. 关键注意事项

  • 禁止跨分片关联:如果两张表分片键不一致,会触发全库全表扫描,性能极差,必须保证关联数据在同一个分片。
  • 复杂查询拆分:若需跨分片查询关联数据,建议拆分逻辑:先查询主表获取分片键集合,再根据分片键批量查询从表,避免直接执行跨分片关联JPQL。
  • 跨库事务处理:需开启ShardingSphere的XA事务或柔性事务,配置示例:
spring:
  shardingsphere:
    rules:
      transaction:
        default-type: XA
        provider-type: Atomikos

内容的提问来源于stack exchange,提问作者dead programmer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 15:38:37