栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

mysql分库分表

mysql分库分表

一、如何进行分库分表 1、概念:

将原本存储在单个数据库上的数据拆分到多个数据库中(分库),把原来存储在单张表的数据拆分到多张数据表中,实现数据切分,从而提生数据库操作性能。分库分表的实现方式分为两种:垂直切分,水平切分。

2、水平拆分:

将数据分散到多张表,涉及到分区键。

分库:每个库结构一样,数据不一样,没有交集。库多了可以缓解io和cpu压力。分表:每个表结构一样,数据不一样,没有交集。表数量减少,可以提高sql执行效率,减轻cpu压力。

优缺点:

优点:

单库(表)的数据保持在一定的量(减少),有助于性能的提高。拆分结构相同,程序改造较小 缺点:

数据扩容有难度,维护量大。拆分规则很难抽象出来分片事务的一致性的问题,部分业务无法关联。 3、垂直拆分:

将字段拆分为多张表,需要一定的重构。

分库:每个库结构,数据都不一样,所有库的并集为全量数据。分表:每个表结构、数据不一样,至少有一列交集,用于关联数据,所有表的并集为全量数据。

优缺点:

优点:

拆分后业务清晰(专库专用按业务拆分)数据维护简单、按业务不同放到不同机器上。 缺点:

单表数据量大,写和读的压力大受某种业务来决定或者被限制。也就是说一个业务往往会影响到数据库的瓶颈(性能问题)。 二、分库分表开源框架 1、jdbc直连层

shardingshpere、tddl(淘宝)

优点:快速性能高、支持跨数据库

缺点:不支持跨语言。

2、proxy代理层

mycat、mysql-proxy

优点:需要网络、支持跨平台、跨语言

缺点:性能比jdbc低、不支持跨数据库

三、分库分表存在的问题 1、分布式事务

ACID(原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性)

当我们在进行多个数据库CURD(增删改查)操作的时候,如果出现错误,那么事务在回滚时只支持一个数据库的回滚,而其他数据库则是会操作成功,那么就会出现脏数据的出现。数据一致性不会得到保证

2、分布式id

在分表中存在,自增id会存在id重复的情况。

3、分布式查询 join

join查询存在数据组合问题。

4、多数据库源管理 四、springboot整合shareingshere 1、导入依赖

    org.apache.shardingsphere
    sharding-jdbc-spring-boot-starter
    4.1.1

2、配置
spring:
  shardingsphere:
    datasource:
      names: master,slave
      commoun:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/shop?serverTimezone=UTC&characterEncoding=utf8&useUnicode=tr&ueuseSSL=false
        username: root
        password: root
        hikari:
          # 连接池最小空闲连接数
          minimum-idle: 5
          # 连接池允许的最大连接数
          maximum-pool-size: 10
          # 等待连接池分配连接的最大时长(毫秒)
          connection-timeout: 30000
      master:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/shop?serverTimezone=UTC&characterEncoding=utf8&useUnicode=tr&ueuseSSL=false
        username: root
        password: root
      slave:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://localhost:3306/shop?serverTimezone=UTC&characterEncoding=utf8&useUnicode=tr&ueuseSSL=false
        username: root
        password: root
    props:
      sql:
        show: true
mybatis:
  configuration:
    # 数据库下划线转驼峰配置
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath*:/mybatis/mapper/*.xml
3、分片配置
 sharding:
      tables:
        employee:
          actualDataNodes: master.employee_$->{0..2}
          tableStrategy:
            inline:
              shardingColumn: id
              algorithmexpression: employee_$->{id % 2}
          keyGenerator:
            type: SNOWFLAKE
            column: id
          #进行分库配置 按照id进行分库
      binding-tables: employee
#          databaseStrategy:
#            inline:
#              shardingColumn: id
#              algorithmexpression: employee_$->{id % 2}
4、读写分离与分片整合配置
    sharding:
      binding-tables: employee
      tables:
        employee:
          actualDataNodes: ms.employee_$->{0..2}
          tableStrategy:
            inline:
              shardingColumn: d_id
              algorithmexpression: employee_$->{d_id % 2}
          keyGenerator:
            type: SNOWFLAKE
            column: d_id
      default-table-strategy:
        none:
      default-key-generator:
        type: SNOWFLAKE
        column: d_id
      default-data-source-name: master
      master-slave-rules:
        ms:
          slave-data-source-names: slave
          load-balance-algorithm-type: round_robin
          master-data-source-name: master
五、测试 1、测试查询
@GetMapping("select")
public List insertDept(Employee employee) {
    return employeeMapper.getEmp(employee);
}

数据库中进行水平分表。

查询所有:


查询在slave中进行查询

2、测试插入
@GetMapping("insert")
public Long insert(Employee employee) {
    employee.setDId(12L);
    employee.setGender(1);
    employee.setDate(new Date());
    employee.setEmail("123121312@12312");
    employeeMapper.insertEmp(employee);
    return employee.getId();
}

插入一条数据


    INSERT INTO employee(lastName, email, gender, d_id, date)
    VALUES (#{lastName}, #{email}, #{gender}, #{dId}, #{date})

插入会在master进行

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/711572.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号