【Springboot系列】一篇文章搞定数据库分库分表,Sharding jdbc真他喵的好用

目录

1、了解分库分表的概念和原理

1.1 分库的场景

1.2 分表的场景

1.3 数据库拆分的两种方式

1.4 分库分表的技术方案

2、Sharding-jdbc 的架构和配置

2.1 sharding jdbc的架构

2.2 sharding jdbc 概念

2.3 show me the code

3、总结


1、了解分库分表的概念和原理

随着数据库的使用,在面对大量数据的存储,单机性能没法解决问题的情况下,就需要考虑分库分表。

1.1 分库的场景

分库一般是单机有性能瓶颈,一般来说IO瓶颈和CPU瓶颈,在单机数据量太大时,无法应对,网络贷款不够,需要多个节点进行负载,这个时候就需要分库。

IO瓶颈一般在面临大数据查询的时候,返回的数据过多,产生大量的IO,单机无法支撑

CPU瓶颈在做一些复杂操作的时候,比如group by ,order by的时候,需要大量cpu运算的时候,

1.2 分表的场景

分表一般是因为单表数据量过多,查询慢,新增也慢,一般来说单表数据不超过2000w,在1000w的时候就要拆份额

1.3 数据库拆分的两种方式

垂直拆分:根据业务维度,将一张表中的字段拆分成不同的几张表

水平拆分: 将一个表根据分片算法,将数据拆分成好几张表结构相同的表

1.4 分库分表的技术方案

1.4.1 客户端主动访问不同数据库

客户端知道数据在哪个地方,直接操作多个多数据,这也就是多数据源

1.4.2 服务端应用进行分开查询

应用下层直接操作分割,技术实现就是sharding-jdbc

1.4.3 中间件进行分开查询

不直接连接到数据源,而是连接到中间件,分库分表的逻辑在中间件实现,技术实现就是mycat

1.5 分片策略

1.5.1 按照哈希切片

对数据库的某个字段进行来求哈希,再除以分片总数后取模,取模后相同的数据为一个分片,这样将数据分成多个分片的方法叫做哈希分片

1.5.2 按时间分表

根据业务时间或者插入时间

1.5.3 按数据区间分表

根据业务数据的范围进行分表

1.6 分库分表存在的问题

我们发现垂直拆分和水平拆分具有共同点:

存在分布式事务问题

存在跨节点join的问题

存在跨节点合并排序、分页的问题

存在多数据源管理的问题

2、Sharding-jdbc 的架构和配置

sharding jdbc 主要是为了解决数据分片和读写分离,使用sharding jdbc 应用可以透明的访问多个数据源和数据表。

2.1 sharding jdbc的架构

Sharding-jdbc 系统架构分成5个部分:SQL解析,SQL路由,SQL改写,SQL执行,结果集归并

2.2 sharding jdbc 概念

2.2.1 逻辑表

水平拆分的数据表的总称。例:订单数据表根据主键尾数拆分为10张表,分别是 torder0 、 torder1 到torder9 ,他们的逻辑表名为 t_order 。

2.2.2 真实表

在分片的数据库中真实存在的物理表。即上个示例中的 torder0 到 torder9 。

2.2.3 数据节点

数据分片的最小物理单元。由数据源名称和数据表组成,例:ds0.torder_0 。

2.3 show me the code

2.3.1 引用

创建一个springboot项目,这个没难度,一路next就好

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--druid数据源-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid}</version>
        </dependency>

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

2.3.2 配置application.properties

这是一个比较全的例子,主从配置,分库,分表

分库 ms单库分库分为 ms0库 和 ms1库。

分表 tab_user单表分为tab_user0表 和 tab_user1表。

读写分离 数据写入ms0库 和 ms1库,数据读取 sl0库 和 sl1库。

server.port=8088
#指定mybatis信息
mybatis.config-location=classpath:mybatis-config.xml
#打印sql
spring.shardingsphere.props.sql.show=true

spring.shardingsphere.datasource.names=master0,slave0,master1,slave1

spring.shardingsphere.datasource.master0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master0.url=jdbc:mysql://localhost:3306/ms0?characterEncoding=utf-8
spring.shardingsphere.datasource.master0.username=root
spring.shardingsphere.datasource.master0.password=root

spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave0.url=jdbc:mysql://localhost:3306/sl0?characterEncoding=utf-8
spring.shardingsphere.datasource.slave0.username=root
spring.shardingsphere.datasource.slave0.password=root

spring.shardingsphere.datasource.master1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master1.url=jdbc:mysql://localhost:3306/ms1?characterEncoding=utf-8
spring.shardingsphere.datasource.master1.username=root
spring.shardingsphere.datasource.master1.password=root

spring.shardingsphere.datasource.slave1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave1.url=jdbc:mysql://localhost:3306/sl1?characterEncoding=utf-8
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=root

#根据年龄分库
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=age
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=master$->{age % 2}
#根据id分表
spring.shardingsphere.sharding.tables.tab_user.actual-data-nodes=master$->{0..1}.tab_user$->{0..1}
spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.tab_user.table-strategy.inline.algorithm-expression=tab_user$->{id % 2}

#指定master0为主库,slave0为它的从库
spring.shardingsphere.sharding.master-slave-rules.master0.master-data-source-name=master0
spring.shardingsphere.sharding.master-slave-rules.master0.slave-data-source-names=slave0
#指定master1为主库,slave1为它的从库
spring.shardingsphere.sharding.master-slave-rules.master1.master-data-source-name=master1
spring.shardingsphere.sharding.master-slave-rules.master1.slave-data-source-names=slave1

2.3.3正常的操作数据库就行

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 模拟插入数据
     */
    List<User> userList = Lists.newArrayList();
    /**
     * 初始化插入数据
     */
    @PostConstruct
    private void getData() {
        userList.add(new User(1L,"小A", "女", 3));
        userList.add(new User(2L,"小B", "男", 31));
        userList.add(new User(3L,"小C", "女", 11));
        userList.add(new User(4L,"小D", "男", 44));
        userList.add(new User(5L,"小E", "女", 62));
    }
    /**
     * @Description: 批量保存用户
     */
    @PostMapping("save-user")
    public Object saveUser() {
        return userService.insertForeach(userList);
    }
    /**
     * @Description: 获取用户列表
     */
    @GetMapping("list-user")
    public Object listUser() {
        return userService.list();
    }
   }

2.3.4 验证下

写入的数据在主库

读出的数据在从库

3、总结

MySQL在面对大数据量、高并发、读写分离、横向扩展、地域分布等情况时,都需要进行分库分表。

只要能满足需求,拆分规则越简单越好

能不搞这些就不搞这些


自媒体写作变现一本通:450万粉丝矩阵主理人、十点读书签约写作讲师手把手教你写作变现实战经验,有方法,有理论,有实践,让写作变现变得简单!

450万粉丝矩阵主理人经验总结,手把手教你写作变现。

当当自营购买链接:http://product.dangdang.com/29511376.html


猜你喜欢

转载自blog.csdn.net/perfect2011/article/details/129647914
今日推荐