• 分库分表利器——shardingJdbc


    一、分库分表方式

    1.1 垂直切分

    1.1.1 垂直分表(拆分字段——但每张表的数据量是不变的)

    把一张表的一部分字段存在一张新表里面,将另一部分字段存在另一张新表中
    在这里插入图片描述

    1.1.2 垂直分库(专库专表)

    把单一数据库按照业务拆分,专库专表,减少单一数据库压力
    在这里插入图片描述

    1.2 水平切分

    1.2.1 水平分表

    在原数据表的基础上复制几份结构相同的副本数据表,再根据特定的规则进行读取,进一步减少单表压力
    在这里插入图片描述

    1.2.2 水平分库

    在原数据库的基础上复制几份结构相同的副本数据库,再根据特定的规则进行读取,进一步缓解单库压力
    在这里插入图片描述

    二、分库分表的应用和问题

    2.1 应用

    (1)在数据库设计时就要考虑垂直分库和垂直分表
    (2)随着数据量的不断增加,不要马上考虑做水平切分,首先考虑缓存处理、读写分离、索引等方式,如果这些方式不能根本解决问题,再考虑做水平分库和分表

    2.2 问题

    (1)跨节点连接查询(当要连接查询时,需要去不同的数据库单独查出来再进行数据拼接汇总)
    在这里插入图片描述

    (2)多数据源管理问题

    三、sharding-Jdbc(轻量的Java框架、JDBC的增强版)

    它并不是做分库分表,而是对分库分表之后的数据表做相关操作,主要功能:数据分片、读写分离

    3.1 水平分表

    3.1.1 环境搭建

    (1)创建一个数据库course_db及两张表,分别为course_1和course_2,两者表结构相同
    在这里插入图片描述

    (2)引入依赖

    
    <dependency>
      <groupId>com.alibabagroupId>
      <artifactId>druid-spring-boot-starterartifactId>
      <version>1.2.11version>
    dependency>
    
    <dependency>
      <groupId>com.baomidougroupId>
      <artifactId>mybatis-plus-boot-starterartifactId>
      <version>3.4.3.4version>
    dependency>
    
    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>5.1.49version>
    dependency>
    
    <dependency>
      <groupId>org.apache.shardingspheregroupId>
      <artifactId>sharding-jdbc-spring-boot-starterartifactId>
      <version>4.0.0-RC1version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    (3)配置文件(官方文档

    # shardingjdbc 分片策略
    
    # 配置数据源,给数据源起名称
    spring.shardingsphere.datasource.names=db1
    
    # 一个实体类对应多张表,覆盖
    spring.main.allow-bean-definition-overriding=true
    
    # 配置数据源具体内容,包含连接池,驱动,地址,用户名和密码
    spring.shardingsphere.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
    spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.db1.url=jdbc:mysql://127.0.0.1:3306/course_db?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
    spring.shardingsphere.datasource.db1.username=root
    spring.shardingsphere.datasource.db1.password=root
    
    # 指定course表分布情况,配置表在哪个数据库里面,表名称都是什么 m1.course_1, m1.course_2
    spring.shardingsphere.sharding.tables.course.actual-data-nodes=db1.course_$->{1..2}
    
    # 指定course表的主键生成策略
    spring.shardingsphere.sharding.tables.course.key-generator.column=cid
    spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
    
    # 数据表分片策略 约定cid为偶数存course_1表, 为奇数存course_2表
    spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
    spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}
    
    # 开启sql输出日志
    spring.shardingsphere.props.sql.show=true
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    (4)插入数据测试

        @Test
        public void addCourse() {
        for (int i = 1; i < 10; i++) {
            Course course = new Course();
            course.setCname("Java "+i);
            course.setUserId(100L);
            course.setCstatus("Normal");
            courseMapper.insert(course);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    在这里插入图片描述
    主键cid是偶数的全部分在了course_1表,奇数分在了course_2表
    (5)查询测试

        @Test
        public void selectCourse() {
            QueryWrapper<Course> wrapper = new QueryWrapper<>();
            wrapper.eq("cid",770051025917706241L);
            System.out.println(courseMapper.selectOne(wrapper));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述
    770051025917706241是奇数,所以查询还是在course_2表

    3.2 水平分库

    3.2.1 环境搭建

    (1)创建两个结构相同的数据库
    在这里插入图片描述
    数据库规则:
    userid为偶数时添加到edu_db_1数据库,为奇数时添加到edu_db_2数据库
    表规则:
    cid为偶数时添加到course_1表,为奇数时添加到course_2表
    在这里插入图片描述
    (2)配置文件

    # shardingjdbc 分片策略(水平分库)
    # 配置数据源,给数据源起名称(对应两个数据库)
    spring.shardingsphere.datasource.names=db1,db2
    
    # 一个实体类对应多张表,覆盖
    spring.main.allow-bean-definition-overriding=true
    
    # 配置第一个数据源具体内容,包含连接池,驱动,地址,用户名和密码
    spring.shardingsphere.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
    spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.db1.url=jdbc:mysql://127.0.0.1:3306/edu_db_1?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
    spring.shardingsphere.datasource.db1.username=root
    spring.shardingsphere.datasource.db1.password=root
    
    # 配置第二个数据源具体内容,包含连接池,驱动,地址,用户名和密码
    spring.shardingsphere.datasource.db2.type=com.alibaba.druid.pool.DruidDataSource
    spring.shardingsphere.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.db2.url=jdbc:mysql://127.0.0.1:3306/edu_db_2?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
    spring.shardingsphere.datasource.db2.username=root
    spring.shardingsphere.datasource.db2.password=root
    
    # 指定数据库分布情况,数据表分布情况
    # db1 db2      course_1  course_2
    spring.shardingsphere.sharding.tables.course.actual-data-nodes=db$->{1..2}.course_$->{1..2}
    # 指定course表的主键生成策略
    spring.shardingsphere.sharding.tables.course.key-generator.column=cid
    spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
    # 指定数据库分片策略(默认的,也就是对全部表的user_id字段都生效)
    #spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
    #spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=edu_db_$->{user_id%2+1}
    # 指定数据库分片策略(指定表的某些字段生效)
    spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
    spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=db$->{user_id % 2+1}
    # 数据表分片策略 约定cid为偶数存course_1表, 为奇数存course_2表
    spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
    spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}
    # 开启sql输出日志
    spring.shardingsphere.props.sql.show=true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    (3)测试

        @Test
        public void insertCourse() {
        for (int i = 1; i <= 10; i++) {
            Course course = new Course();
            //数据库(偶数在1 奇数在2)
            course.setUserId(11L);
            course.setCname("水平分库-" + i);
            course.setCstatus("Normal");
            courseMapper.insert(course);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    user_id为偶数存1号库,user_id为奇数存2号库;
    cid为偶数存1号表,cid为奇数存2号表
    在这里插入图片描述
    在这里插入图片描述

    3.3 垂直分库(专库专表)

    3.3.1 环境搭建

    (1)创建数据库
    在上面水平分库的基础上再添加一个一个数据库user_db,并创建一张表t_user
    在这里插入图片描述
    (2)配置文件

    # shardingjdbc 分片策略(垂直分库————专库专表)
    # 配置数据源,给数据源起名称(对应两个数据库)
    spring.shardingsphere.datasource.names=db1,db2,db3
    
    # 一个实体类对应多张表,覆盖
    spring.main.allow-bean-definition-overriding=true
    
    # 配置第一个数据源具体内容,包含连接池,驱动,地址,用户名和密码
    spring.shardingsphere.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource
    spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.db1.url=jdbc:mysql://127.0.0.1:3306/edu_db_1?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
    spring.shardingsphere.datasource.db1.username=root
    spring.shardingsphere.datasource.db1.password=root
    
    # 配置第二个数据源具体内容,包含连接池,驱动,地址,用户名和密码
    spring.shardingsphere.datasource.db2.type=com.alibaba.druid.pool.DruidDataSource
    spring.shardingsphere.datasource.db2.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.db2.url=jdbc:mysql://127.0.0.1:3306/edu_db_2?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
    spring.shardingsphere.datasource.db2.username=root
    spring.shardingsphere.datasource.db2.password=root
    
    # 配置第三个数据源具体内容,包含连接池,驱动,地址,用户名和密码
    spring.shardingsphere.datasource.db3.type=com.alibaba.druid.pool.DruidDataSource
    spring.shardingsphere.datasource.db3.driver-class-name=com.mysql.jdbc.Driver
    spring.shardingsphere.datasource.db3.url=jdbc:mysql://127.0.0.1:3306/user_db?useUnicode=true&&characterEncoding=utf-8&&useSSL=false
    spring.shardingsphere.datasource.db3.username=root
    spring.shardingsphere.datasource.db3.password=root
    
    #--------------------------------------user_db数据库里面t_user 专库专表----------------------------------------------
    # 配置user_db数据库里面t_user专库专表
    spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=db3.t_user
    
    # 指定course表的主键生成策略
    spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
    spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE
    
    # 数据表分片策略 user表
    spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding-column=user_id
    spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm-expression=t_user
    
    #----------------------------------------edu_db_数据库里面course表 水平分库--------------------------------------------
    # 配置edu_db_数据库里面course表的情况
    spring.shardingsphere.sharding.tables.course.actual-data-nodes=db$->{1..2}.course_$->{1..2}
    
    # 指定course表的主键生成策略
    spring.shardingsphere.sharding.tables.course.key-generator.column=cid
    spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
    
    # 数据表分片策略 约定cid为偶数存course_1表, 为奇数存course_2表
    spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=cid
    spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{cid % 2+1}
    
    # 指定数据库分片策略(默认的,也就是对全部表的user_id字段都生效)
    #spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=user_id
    #spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=edu_db_$->{user_id%2+1}
    
    # 指定数据库分片策略(指定表的某些字段生效)
    spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=user_id
    spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=db$->{user_id % 2+1}
    
    # 开启sql输出日志
    spring.shardingsphere.props.sql.show=true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62

    (3)测试

    @Test
        public void addUser(){
        User user = new User();
        user.setUsername("lucy");
        user.setUstatus("Normal");
        userMapper.insert(user);
    }
    
    @Test
        public void findUser(){
        List<User> users = userMapper.selectList(null);
        System.out.println(users);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    注意:数据表对应的实体类表名一定要和数据库表名相同(一定要能对应,否则可能会抛datasourse is null的异常)——最好指明数据库表名

    四、Sharding-JDBC操作公共表

    4.1 公共表

    (1)存储固定数据的表,表数据很少发生变化,查询时经常进行关联
    (2)在每个数据库中都有结构完全相同的表
    实现操作公共表,也就是对每个数据库中的公共表同时进行添加、修改、删除操作
    添加配置:

    # 配置公共表
    spring.shardingsphere.sharding.broadcast-tables=t_common
    spring.shardingsphere.sharding.tables.t_common.key-generator.column=common_id
    spring.shardingsphere.sharding.tables.t_common.key-generator.type=SNOWFLAKE
    
    • 1
    • 2
    • 3
    • 4

    五、读写分离

    5.1 概念

    为了确保数据库的稳定性,大多拥有双机热备的功能,原理:主数据库(master)处理事务性增、删、改操作;从数据库(slave)处理select操作。
    在这里插入图片描述

    主从复制:当主服务器有写操作时,从服务器自动获取
    原理:从服务器实时监控主服务器的binlog日志,当用户对主服务器进行写操作时改变了binlog日 志,从服务器拉取binlog日志读取并解析执行。从而实现与主数据库达到同步效果。

    读写分离:写操作在主服务器,读操作在从服务器

    5.2 mysql配置读写分离

    (1)创建两个mysql数据库服务
    直接复制之前mysql安装根目录,
    在这里插入图片描述
    修改配置(端口号、安装目录、数据存放目录),
    在这里插入图片描述
    为修改后的从数据库安装windows服务,mysqls1是服务名
    cmd管理员权限:
    注册服务

    mysqld install mysqls1 --defaults-file=“D:\code\mysql-5.7.23-winx64-s1\my.ini”

    删除服务

    sc delete 服务名称
    在这里插入图片描述
    连接从数据库,
    在这里插入图片描述
    (2)配置mysql主从数据库
    修改主数据库配置文件my.ini

    [mysqld]
    #开启日志
    log-bin = mysql-bin
    #设置服务id,主从不能一致
    server-id = 1
    #选择ROW模式
    binlog_format=ROW
    #设置需要同步的数据库
    binlog-do-db=user_db
    #屏蔽系统库同步
    binlog-ignore-db=mysql
    binlog-ignore-db=information_schema
    binlog-ignore-db=performance_schema
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    修改从数据库配置文件my.ini

    [mysqld]
    #从服务器配置
    #开启日志
    log-bin=mysql-bin
    #设置服务id,主从不能一致
    server-id=2
    #选择ROW模式
    binlog_format=ROW
    #设置需要同步的数据库
    replicate_wild_do_table=user_db.%
    #屏蔽系统库同步
    replicate_wild_ignore_table=mysql.%
    replicate_wild_ignore_table=information-schema.%
    replicate_wild_ignore_table=performance_schema.%
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
  • 相关阅读:
    本地开发环境和服务器传输数据的几种方法
    NX/UG二次开发—Parasolid—PK_BODY_pick_topols
    华为终端智能家居应用方案
    个人电影网站web网页设计制作—— 影视公司5页 DIV+CSS制作 浮动布局
    pytorch 中 nn.ModuleList()使用说明
    Web-过滤器
    08c++呵呵老师【给子弹添加爆炸效果】
    JVM-JVM中对象的结构
    云耀服务器L实例部署Nextcloud企业云盘系统|华为云云耀云服务器L实例评测使用体验
    LeetCode 141. 环形链表 和 142. 环形链表 II
  • 原文地址:https://blog.csdn.net/weixin_42194695/article/details/127934931