一、数据库分库分表规则

1、什么是垂直/水平拆分模式

垂直拆分:公司根据不同的业务来拆分成不同的数据库

应用场景:微服务(订单、会员、支付)

缺点:分布式事务问题

水平拆分:单张表数据量达到500w条,可能会遇到查询瓶颈,比如:分页和排序

将单张表数据放入到多个不同的数据库中,或者将单表拆分成N个子表存放进行查询

缺点:查询问题 分页/排序可能会引发内存溢出问题

2、基于客户端/服务器端实现分表分库区别

数据库中间件:mycat或者ShardingJDBC

基于服务器端-mycat:

优点:归并数据结果是完全解耦合,保证数据的安全性

缺点:效率偏低

基于客户端-ShardingJDBC

优点:效率高

缺点:归并数据结果没有实现解耦合,有可能会影响业务逻辑

原理:基于aop代理方式拦截改写sql

例如:select * from user -> select * from user_0, select * from user_1

3、单表达到多少数据量开始分表分库

【推荐】单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

4、数据库分表分库策略有哪些

取余/取模

按照范围分片

按照日期进行分片

按照月份进行分片

按照枚举进行分片

二进制取模范围分片

一致性hash分片

按照目标字段前缀指定的进行分区

按照前缀ASCII码和值进行取模范围分片

二、项目实例

1、application.yml

server:
  port: 9091
mybatis-plus:
  type-aliases-package: cn.itcloud.sharedingjdbc.entity
  mapper-locations: classpath:mapper/*.xml
  configuration:
    jdbc-type-for-null: null
  global-config:
    banner: false
    #db-config:
    # select-strategy: not_empty
    select-strategy: not_empty
    insert-strategy: not_empty
    update-strategy: not_empty
sharding:
  jdbc:
    datasource:
      names: ds-master #随便写
      #主库
      ds-master:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://127.0.0.1:3306/shardingjdbcdb?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2b8
        username: root
        password: root
    #水平拆分的数据库(表)配置分库 + 分表策略 行表达式分片策略
    config:
      sharding:
        #        defult-database-strategy:
        #          inline:
        #            sharding-column: id
        #            algorithm-expression: shardingjdbcdb
        #            # 分表策略 其中user为逻辑表 分表主要取决于ID字段
        tables:
          user:  #user是逻辑表名称
            actual-data-nodes: ds-master.user_$->{0..1}  #0..1 从0到1
            table-strategy:
              inline:
                sharding-column: id
                #分片算法表达式
                algorithm-expression: user_$->{id % 2}
      #打印执行的数据库
      props:
        sql:
          show: true
#打印执行的sql语句
spring:
  main:
    allow-bean-definition-overriding: true

 2、pom.xml

最主要的的依赖

<!--io.shardingsphere-->
 <dependency>
     <groupId>io.shardingsphere</groupId>
     <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
     <version>3.1.0</version>
 </dependency>
 <!-- sharding-jdbc-spring-namespace -->
 <dependency>
     <groupId>io.shardingsphere</groupId>
     <artifactId>sharding-jdbc-spring-namespace</artifactId>
     <version>3.1.0</version>
 </dependency><dependency>
	<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.5.1</version>
</dependency>
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.79</version>
</dependency>
<!--常用工具类 -->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
</dependency>
<!--io.shardingsphere-->
<dependency>
	<groupId>io.shardingsphere</groupId>
	<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
	<version>3.1.0</version>
</dependency>
<!-- sharding-jdbc-spring-namespace -->
<dependency>
	<groupId>io.shardingsphere</groupId>
	<artifactId>sharding-jdbc-spring-namespace</artifactId>
	<version>3.1.0</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<optional>true</optional>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>
<!--mybatis-plus-->
<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.5.1</version>
</dependency>
<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>fastjson</artifactId>
	<version>1.2.79</version>
</dependency>
<!--常用工具类 -->
<dependency>
	<groupId>org.apache.commons</groupId>
	<artifactId>commons-lang3</artifactId>
</dependency>
<!--io.shardingsphere-->
<dependency>
	<groupId>io.shardingsphere</groupId>
	<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
	<version>3.1.0</version>
</dependency>
<!-- sharding-jdbc-spring-namespace -->
<dependency>
	<groupId>io.shardingsphere</groupId>
	<artifactId>sharding-jdbc-spring-namespace</artifactId>
	<version>3.1.0</version>
</dependency>

3、User实体类

package cn.itcloud.sharedingjdbc.entity;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

/**
 * @author zqing
 * @description: TODO
 * @date: 2022/3/11 14:58
 */
@Data
@TableName("user") //逻辑表名称:user,分表为:user_01,user_02
public class User {

    private Integer id;

    private String userName;

    private Integer age;

    public User(Integer id, String userName, Integer age) {
        this.id = id;
        this.userName = userName;
        this.age = age;
    }
}

4、UserMapper-分页查询和排序

package cn.itcloud.sharedingjdbc.mapper;

import cn.itcloud.sharedingjdbc.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @author zqing
 * @description: TODO
 * @date: 2022/3/11 15:01
 */
public interface UserMapper extends BaseMapper<User> {
    /**
     * 查询所有
     * @return
     */
    @Select("select * from user")
    List<User> getList();


    /**
     * 分页查询
     * @return
     */
    @Select("select * from user limit 0,2")
    List<User> getListPage();

    /**
     * 排序
     * @return
     */
    @Select("select * from user order by id desc")
    List<User> getListOrderBy();

    @Select("select *  from user where id = #{id}")
    List<User> getListById(Integer id);

}