# sharding-jdbc **Repository Path**: jin_apache/sharding-jdbc ## Basic Information - **Project Name**: sharding-jdbc - **Description**: sharding-jdbc分库分表演示demo项目 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2022-03-20 - **Last Updated**: 2022-03-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### 一、序言 在实际业务中,单表数据增长较快,很容易达到数据瓶颈,比如单表百万级别数据量。当数据量继续增长时,数据的`查询性能`即使有索引的帮助下也不尽如意,这时可以引入数据`分库分表`技术。 本文将基于`SpringBoot`+`MybatisPlus`+`Sharding-JDBC`+Mysql实现企业级分库分表。 ##### 1、组件及版本选择 | ![SpringBoot2](https://www.altitude.xin/typora/SpringBoot2.png) | ![MybatisPlus2](https://www.altitude.xin/typora/MybatisPlus2.png) | ![Sharding-JDBC](https://www.altitude.xin/typora/Sharding-JDBC.png) | ![Mysql](https://www.altitude.xin/typora/Mysql.png) | | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------- | | SpringBoot 2.6.x | MybatisPlus 3.5.0 | Sharding-JDBC 4.1.1 | Mysql 5.7.35 | ##### 2、预期目标 - 使用上述组件实现分库分表,简化起见只讨论分表技术 - 完成分表后的逻辑表与物理表间的增删查改 - 引入逻辑删除和使用MybatisPlus内置分页技术 完整项目源码[访问地址](https://gitee.com/decsa/springdata-demo/tree/master/sharding-jdbc)。 ### 二、代码实现 为了简化分表复杂性,专注于分表整体实现,简化分表逻辑:按照`UserId`的奇偶属性分别进行分表。以订单表这一典型场景为例,一般来说有关订单表,通常具有如下共性行为: - 创建订单记录 - 查询XX用户的订单列表 - 查询XX用户的订单列表(分页) - 查询XX订单详情 - 修改订单状态 - 删除订单(逻辑删除) 接下来通过代码实现上述目标。 #### (一)素材准备 ##### 1、实体类 ```java @Data @TableName("bu_order") public class Order { @TableId private Long orderId; private Integer orderType; private Long userId; private Double amount; private Integer orderStatus; @TableLogic @JsonIgnore private Boolean deleted; } ``` ##### 2、Mapper类 ```java @Mapper public interface OrderMapper extends BaseMapper { } ``` ##### 3、全局配置文件 ```yaml spring: config: use-legacy-processing: true shardingsphere: datasource: ds1: driver-class-name: com.mysql.cj.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://127.0.0.1:3306/sharding-jdbc2?serverTimezone=UTC username: root password: 123456 names: ds1 props: sql: show: true sharding: tables: bu_order: actual-data-nodes: ds1.bu_order_$->{0..1} key-generator: column: order_id type: SNOWFLAKE table-strategy: inline: algorithm-expression: bu_order_${user_id%2} sharding-column: user_id ``` #### (二)增删查改 ##### 1、保存数据 由于依据主键的奇偶属性对原表分表,分表后每张表的数据量是分表前的二分之一。根据需要也可以自定义分表数量(比如10张),新分表后的数据量是不分表前的十分之一。 ```java @Test public void addOrders() { for (long i = 1; i <= 10; i++) { Order order = new Order(); order.setOrderId(i); order.setOrderType(RandomUtil.randomEle(Arrays.asList(1, 2))); order.setUserId(RandomUtil.randomEle(Arrays.asList(101L, 102L, 103L))); order.setAmount(1000.0 * i); orderMapper.insert(order); } } ``` ##### 2、查询列表数据 查询指定用户的订单列表。 ```java @GetMapping("/list") public AjaxResult list(Order order) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(order); return AjaxResult.success(orderMapper.selectList(wrapper)); } ``` ##### 3、分页查询数据 分页查询指定用户的订单列表 ```java @GetMapping("/page") public AjaxResult page(Page page, Order order) { return AjaxResult.success(orderMapper.selectPage(page, Wrappers.lambdaQuery(order))); } ``` ##### 4、查询详情 通过订单ID查询订单详情。 ```java @GetMapping("/detail/{orderId}") public AjaxResult detail(@PathVariable Long orderId) { return AjaxResult.success(orderMapper.selectById(orderId)); } ``` ##### 5、删除数据 通过订单ID删除订单(逻辑删除) ```java @DeleteMapping("/delete/{orderId}") public AjaxResult delete(@PathVariable Long orderId) { return AjaxResult.success(orderMapper.deleteById(orderId)); } ``` ##### 6、修改数据 修改数据一般涉及部分列,比如修改订单表的订单状态等。 ```java @PutMapping("/edit") public AjaxResult edit(@RequestBody Order order) { return AjaxResult.success(orderMapper.updateById(order)); } ``` ### 三、理论分析 ##### 1、选择分片列 选择分片列是经过精心对比后确定的,对于订单类场景,需要频繁以用户ID为查询条件筛选数据,因此将同一个用户的订单数据存放在一起有利于提高查询效率。 ##### 2、扩容 当分表后的表数据快速增长,可以预见即将达到瓶颈时,需要对分表进行扩容,扩容以`2倍`的速率进行,扩容期间需要迁移数据,工作量相对可控。 --- > 喜欢本文点个♥️赞♥️支持一下,关注我下期再见,相关源码在[GitHub](https://gitee.com/decsa),视频讲解在[B站](https://space.bilibili.com/1936685014),本文收藏在[专题博客](http://www.altitude.xin)。