Mysql分库分表

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 Mysql分库分表,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

Mysql分库分表

数据库拆分主要指分库分表,其目的主要是分散数据库压力,达到横向扩展,满足均衡访问等。



一、Mysql分表分库

1.垂直拆分

将不同业务功能相关的表放到不同的数据库中,也就是类似于微服务架构中:订单数据库/支付数据库/会员数据库

2.水平拆分

对同一张表数据实现拆分放到多个不同的表中存放。
【推荐】单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。 摘自:阿里巴巴java开发手册


二、如何分表分库

1.常用数据库中间件

Mycat:基于服务器端 分表分库中间件
优点:能够保证数据库的安全性
缺点:效率比较低

shadingjdbc:基于客户端改写sql 分表分库中间件
优点:效率比较高
缺点:不能够保证数据库的安全性、客户端容易内存溢出

2.分表分库策略

分表分库需要考虑点:扩容性、每张表数据均匀性。

1.取余/取模
优点:可以保证每张表数据均匀性
缺点:后期无法做扩容

2.按照范围分片
优点:容易扩容、每张表数据都是均匀的存放
缺点:前期可能会有数据表空闲

3.按照日期进行分片
优点:容易扩容
缺点:每张表数据不均匀

4.按照枚举值分片
优点:容易扩容
缺点:每张表数据不均匀

5.二进制取模范围分片
6.一致性hash分片
7.按照目标字段前缀指定的进行分区
8.按照前缀ASCII码和值进行取模范围分片


三.Shadingjdbc整合

1.Maven依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.0.RELEASE</version>
</parent>
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.2</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>io.shardingsphere</groupId>
        <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>io.shardingsphere</groupId>
        <artifactId>sharding-jdbc-spring-namespace</artifactId>
        <version>3.1.0</version>
    </dependency>

</dependencies>

2.相关配置

a.整合分表

# 数据源 testdb
sharding:
  jdbc:
    datasource:
      names: testdb
      # 第一个数据库
      testdb:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        jdbc-url: jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
        username: root
        password: root
    # 水平拆分的数据库(表) 配置分库 + 分表策略 行表达式分片策略
    config:
      sharding:
        # 分库策略
        #        default-database-strategy:
        #          inline:
        #            sharding-column: id
        #            algorithm-expression: testdb
        # 分表策略 其中test_user为逻辑表 分表主要取决于id字段
        tables:
          test_user:
            ### testdb test_user_0 test_user_1
            actual-data-nodes: testdb.test_user_$->{0..1}
            table-strategy:
              inline:
                sharding-column: id
                # 分片算法表达式 test_user_1%2 test_user_2%2 test_user_3%2
                algorithm-expression: test_user_$->{id % 2}

      # 打印执行的数据库
      props:
        sql:
          show: true

# 打印执行的sql语句
spring:
  main:
    allow-bean-definition-overriding: true

b.整合分表

# 数据源 testdb
sharding:
  jdbc:
    datasource:
      names: testdb
      # 第一个数据库
      testdb:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        jdbc-url: jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
        username: root
        password: root
    # 水平拆分的数据库(表) 配置分库 + 分表策略 行表达式分片策略
    config:
      sharding:
        tables:
          test_user:
            actual-data-nodes: testdb.test_user_$->{0..1}
            table-strategy:
              standard:
                precise-algorithm-class-name: com.test.config.TestRangeShardingAlgorithm
                sharding-column: id
      # 打印执行的数据库
      props:
        sql:
          show: true

# 打印执行的sql语句
spring:
  main:
    allow-bean-definition-overriding: true

@Slf4j
public class TestRangeShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
    private Long TABLE_SIZE = 5l;
    private String TABLE_NAME = "meite_user";

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
        Double temp = Double.valueOf(preciseShardingValue.getValue()) / TABLE_SIZE;
        String tableName = TABLE_NAME + (int) Math.ceil(temp);
        log.info("<tableName{}>", tableName);
        return tableName;
    }
}


四、分表分库语句查询原理

分表分库之后如何查询的呢?
查询语句没有带上分片字段–查询所有
询语句带上分片字段–根据该分片字段 计算具体表查询

1.查询语句条件后面带上分片字段

截取该查询sql语句中 where 条件后面的分片字段,如果带上了分片字段 ,则根据该分片字段计算出具体存放在哪张表。
只会发送一条sql语句。

2.查询语句条件后面没有带上分片字段

判断该 查询语句没有分片字段,直接查询所有。
将每张表都会查询一遍。

Shadingjdbc建议查询的过程中带上分片的字段

3.分页查询,查询条件且没有带上分片字段

Shadingjdbc 将每张表数据做一个查询,在交给Shadingjdbc 分页 返回给 客户端。

4.排序查询,查询条件且没有带上分片字段

Shadingjdbc 将每张表数据做一个查询,在交给Shadingjdbc 排序 返回给 客户端。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131298.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!