一、数据库分库分表规则
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);
}