一、概念

1、什么是分库分表?为什么要分库分表?

随着业务的增加,数据库的数据量越来越多,当数据量达到1000w或者100G后,数据的查询效率就会越来越低,为了提高效率,把数据量分散在不同的数据库中或者表中,使得单一数据库的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的。

2、分库分表的方式

(1)垂直分表:根据分片规则,将数据分布到不同表中。

(2)水平分表:将相关性低的字段拆分到不同的表中。

(3)垂直分库:根据分片规则,将数据分布到不同的库中。

(4)水平分库:根据业务拆分不同的数据库,比如说一个微服务就对应一个自己的数据库。

二、实现

1、导入shardingJDBC和springboot整合的依赖:

<dependency> 
    <groupId>org.apache.shardingsphere</groupId> 
    <artifactId>sharding‐jdbc‐spring‐boot‐starter</artifactId> 
    <version>4.0.0‐RC1</version> 
</dependency>

2、在application.properties中对分片规则进行配置,分片规则配置是sharding-jdbc进行对分库分表操作的重要依据,配置内容包括:数据源、主键生成策略、分片策略等。

# 定义数据源 
spring.shardingsphere.datasource.names = m1 
spring.shardingsphere.datasource.m1.type = com.alibaba.druid.pool.DruidDataSource 
spring.shardingsphere.datasource.m1.driver‐class‐name = com.mysql.jdbc.Driver 
spring.shardingsphere.datasource.m1.url = jdbc:mysql://localhost:3306/order_db?
useUnicode=true spring.shardingsphere.datasource.m1.username = root 
spring.shardingsphere.datasource.m1.password = root 

# 指定t_order表的数据分布情况,配置数据节点 
spring.shardingsphere.sharding.tables.t_order.actual‐data‐nodes = m1.t_order_$‐>{1..2} 

# 指定t_order表的主键生成策略为SNOWFLAKE 
spring.shardingsphere.sharding.tables.t_order.key‐generator.column=order_id spring.shardingsphere.sharding.tables.t_order.key‐generator.type=SNOWFLAKE 

# 指定t_order表的分片策略,分片策略包括分片键和分片算法 
spring.shardingsphere.sharding.tables.t_order.table‐strategy.inline.sharding‐column = order_id 
spring.shardingsphere.sharding.tables.t_order.table‐strategy.inline.algorithm‐expression = t_order_$‐>{order_id % 2 + 1} 

# 打开sql输出日志 
spring.shardingsphere.props.sql.show = true

(1)、定义数据源,需要分库的数据库

(2)、指定数据节点,即分表的表

(3)、配置主键生成策略,雪花算法

(4)、指定分表策略。可以使用inline表达式的方式,也可以自定义,也可以通过preciseAlgorithmClassName 类的方式自定义分片规则。

如根据时间来对数据进行分片:

 @Override
 public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) {
        
        //配置的分片的sharding-column对应的值
        Date timeValue = shardingValue.getValue();
        String time = DateUtils.dateTimeToString(timeValue, "yyyy-MM-dd HH:mm:ss");

        //分库时配置的sharding-column
        String timeColumn = shardingValue.getColumnName();
        //需要分库的逻辑表
        String tableName = shardingValue.getLogicTableName();

        //按月份路由
        LocalDateTime localDateTime = DateUtils.asLocalDateTime(timeValue);
        int year = localDateTime.getYear();
        int monthValue = localDateTime.getMonthValue();
        int quarter = DateUtils.getQuarter(monthValue);

        for (String each : availableTargetNames) {
            if (each.endsWith(year + "_" + quarter)) {
                return each;
            }
        }
        throw new Exception();
    }

3、测试

三、执行流程

当shardingJDBC接受到一条SQL语句时,会依次执行SQL解析---->SQL路由---->SQL改写

----->SQL执行----->结果归并。

                          

(1)SQL解析:会根据SQL语句进行解析,生成一个SQL的语法树。

(2)SQL路由:根据分片规则进行匹配到具体的哪一个数据库或者表

(3)SQL改写:将SQL中逻辑表改写真实的物理表,结果归并中需要对结果进行排序或者分组的时候,如果原始SQL中的选择项中并不包含分组项或者排序项,则需要对原始SQL进行改写。

(4)SQL执行:执行改写后的SQL语句

(5)结果归并:将结果进行归并

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐