分表?分库?分库分表?实践详谈 ShardingSphere-JDBC

如果有不是很了解ShardingSphere的可以先看一下这个文章:

《ShardingSphere JDBC?Sharding JDBC?》基本小白脱坑问题

阿丹:

        在很多开发场景下面,很多的技术难题都是出自于,大数据量级或者并发的场景下面的。这里就出现了我们要解决的。本文章重点讨论一下在java的spirng开发场景下,有哪些业务场景可以让我们使用下面的三个场景:
        分表?分库?分库分表?

        这个文章的根本就是能让大家可以自己上手使用,以及清楚分表?分库?分库分表?这三种业务场景,来帮助大家可以使用这样的技术来解决业务的难题。

在开始前先给分表?分库?分库分表?这三个业务场景先搞清楚在说。

分库分表:

分库和分表有两种形式,垂直和水平

分库的两种模式:
 

分库:

垂直分库:

也就是说,垂直的将各个领域分开成表。

将不同的垂直的领域来进行分库

水平分库:

将单个性质的数据库,平行拆分多个数据库,对于数据库的命名使用附带逻辑的命名来解决这个问题。

分表:
 

垂直分表:

也就是按照业务维度来将数据进行拆分,将不常用的信息放到一个扩展表中去。

水平分表:

水平也就是将用户做一个水平的分布,展现出来就是user_table_--name这样的方式来展现

什么时候这样做呢?

从两个方向去考虑

1、数据库连接

2、单表数据量

当数据库连接不够的时候,肯定是使用分库的方式来完成这个操作

当单表的数据影响到数据操作的时候,使用分表来完成这个操作。具体多少以上要根据单条数据量级,以及数据内核来计算。

那么什么时候来使用分库分表?

在高并发的写入或者查询的场景下面

以及在数据量非常巨大的情况下面我们就可以开始考虑分库分表来进行操作了。

那分库分表使用什么技术栈呢?

数据库分库分表框架 ShardingSphere

官方操作文档:

ShardingSphere-JDBC :: ShardingSphere

Sharding-JDBC 是一款开源的Java框架,主要用于在数据库层面解决大规模数据存储下的水平扩展问题,即数据分片(sharding)。它通过在应用程序的JDBC层进行增强,使得开发者能够在不改变原有SQL操作习惯的前提下,透明地实现对数据库的分库与分表操作。

Sharding-JDBC的主要特点包括:

  1. 轻量级客户端模式:无需额外部署服务器端中间件,直接作为JDBC驱动集成到应用中,无缝对接各类 ORM 框架及 JDBC 使用场景。

  2. 透明化分片:通过解析SQL语句以及应用自定义的分片规则,自动路由到正确的数据库和表,对于应用层来说,就像是在操作一个完整的逻辑数据库。

  3. 功能全面:支持多数据源、读写分离、分库分表、数据一致性保证(如分布式事务)、灵活的分片策略等,并且提供了丰富的分片算法供用户选择或自定义。

  4. 高性能:由于其工作原理是在客户端完成SQL解析和路由,避免了网络传输开销,理论上性能更优。

  5. 兼容性良好:完全兼容JDBC和大部分ORM框架,可以很容易地整合到现有的基于Java的企业级应用中。

分片键

用于将数据库(表)水平拆分的数据库字段。

分库分表中的分片键(Sharding Key)是一个关键决策,它直接影响了分库分表的性能和可扩展性。以下是一些选择分片键的关键因素:

  1. 访问频率:选择分片键应考虑数据的访问频率。将经常访问的数据放在同一个分片上,可以提高查询性能和降低跨分片查询的开销。
  2. 数据均匀性:分片键应该保证数据的均匀分布在各个分片上,避免出现热点数据集中在某个分片上的情况。
  3. 数据不可变:一旦选择了分片键,它应该是不可变的,不能随着业务的变化而频繁修改。

分片键(Sharding Key)是数据库分片技术中非常关键的概念。在分布式数据库系统或者数据仓库中,当单个数据库实例无法容纳全部数据,或者为了提高并发处理能力和数据访问效率时,往往会采取水平分区的方式,也就是数据分片(Sharding),将数据分布到多个物理节点上。

分片键是指在进行数据分片时,用来确定数据记录应被分配到哪个特定分片上的字段或属性。它是数据分区的依据,根据分片键的值,通过预定义的分片策略(例如哈希、范围、列表等)计算出数据应该存储在哪个分片上。换句话说,分片键的选择直接关系到数据在各个分片之间的分布均衡性、查询性能以及业务需求的满足程度。

例如,如果我们有一个订单表orders,并且按年份进行分片,那么o_orderdate字段就可以作为分片键,每年的订单数据都会被存储在一个特定的数据库分片中。在实际应用中,分片键的选择应当尽量考虑以下因素:

  • 查询模式:选择那些频繁出现在查询条件中且能均匀分布数据的字段。
  • 数据增长趋势:确保分片键能够适应未来数据的增长,避免热点分片。
  • 分区粒度:粒度过大可能造成单个分片过大,粒度过小则可能导致分片过多,影响管理效率和查询效率。

总之,分片键是整个分片机制的核心,合适的分片键能够有效提升分布式数据库系统的可扩展性和可用性。

Sharding-JDBC引入项目

需求:
我要使用ShardingSphere JDBC完成分库,库名为XXXX_2024往后就是按照年份来,每年一个日志的库,Id为雪花算法生成,

分表的原理为XXXXX_0402像这样在表后面追加时间来完成比如今天是4月7号就是在表后面追加0407

引入依赖

ShardingSphere-JDBC配置application.yml文件文件

# application.yml
spring:
  shardingsphere:
    datasource:
      names: ds0 # 数据源名称,可添加更多数据源以支持读写分离
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/chicklogin_record_2024?serverTimezone=UTC
        username: root
        password: password
    sharding:
      tables:
        chick_record: # 表名逻辑名称
          actual-data-nodes: chicklogin_record_$->{2024..2099}.chick_record_$->{0101..1231} # 分库分表策略,假设从2024年开始,每年一个库,每天一个表
          table-strategy:
            standard:
              sharding-column: record_date # 分表依据的字段名
              precise-algorithm-class-name: com.example.CustomDateTableShardingAlgorithm # 自定义分表算法类,处理日期转换为表后缀
          key-generator:
            column: id # 主键列名
            type: SNOWFLAKE # 使用雪花算法作为主键生成器
            props:
              worker-id: 1 # 雪花算法workerId配置,根据实际情况设定

在配置文件中的定义分片规则!!注意:我们在自定义的时候需要给需要分表的一类表,在配置文件中说明如何分配

# application.yml
spring:
  shardingsphere:
    # ...其他配置...
    sharding:
      tables:
        chick_record: # 第一个表配置
          actual-data-nodes: chicklogin_record_$->{2024..2099}.chick_record_$->{0101..1231}
          table-strategy:
            standard:
              sharding-column: record_date
              precise-algorithm-class-name: com.example.CustomDateTableShardingAlgorithm
        order_info: # 第二个表配置
          actual-data-nodes: chicklogin_record_$->{2024..2099}.order_info_$->{0101..1231}
          table-strategy:
            standard:
              sharding-column: order_date
              precise-algorithm-class-name: com.example.CustomDateTableShardingAlgorithm
    # ...其他配置...

配置雪花算法ID生成器

如果使用的是内建的雪花算法主键生成器,通常无需额外配置。但如果需要自定义,也可以实现相关接口。这里默认使用内置的SnowflakeKeyGenerator。

在实体类中使用雪花ID注解

import org.apache.shardingsphere.infra.datanode.DataNode;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Table(name = "chick_record")
public class ChickRecordEntity {

    @Id
    private Long id; // 由雪花算法自动生成

    // 其他属性和getter/setter省略
}

pom依赖

 <!-- Spring Boot Starter Data JPA 或 Spring Boot Starter MyBatis等基础数据库依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId> <!-- 或 spring-boot-starter-mybatis 等 -->
    </dependency>

    <!-- ShardingSphere JDBC核心依赖 -->
    <dependency>
      <groupId>org.apache.shardingsphere</groupId>
      <artifactId>shardingsphere-jdbc-core</artifactId>
      <!-- 检查ShardingSphere官网或Maven仓库获取最新的稳定版本号 -->
      <version>{latest_version}</version>
    </dependency>

    <!-- 如果你的项目中使用了MySQL数据库驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <!-- 根据实际情况填写版本号 -->
      <version>{mysql_driver_version}</version>
      <!-- 若使用Spring Boot,通常可以作为provided或者runtime scope -->
      <scope>runtime</scope>
    </dependency>

 

具体的增删改查还使用MyBatis Plus或其他持久层框架集成-就OK了
这个就不在这个文章中在教大家了,大家可以自行去搜索一下。

注意!!!
 

Apache ShardingSphere-JDBC 提供了一种称为“透明化分片”的能力,通过其内置的优化机制,它可以尽可能地减少跨分片的SQL查询带来的性能损失。为了提高查询效率并避免多次查询不同分片表的情况发生,ShardingSphere-JDBC提供了以下几种机制:

  1. 分片路由优化

    • 对于简单的分片SQL,ShardingSphere-JDBC会根据分片策略智能路由至正确的数据源和表,确保一次查询仅访问必要的分片。
  2. 广播表

    • 广播表是指在所有分片库中完全复制的一张表,用于存储全局唯一或者不需要分片的数据。查询广播表时,ShardingSphere-JDBC会在所有数据源上执行相同的查询,并将结果合并返回。
  3. 笛卡尔积连接消除

    • 当SQL中有多个分片表参与JOIN查询时,默认情况下ShardingSphere-JDBC会尽量避免产生不必要的笛卡尔积,而是通过分析查询条件,找出最优的连接顺序和范围,减少分片间的数据交互。
  4. 多表关联查询优化

    • 对于涉及多个分片表的复杂查询,如果满足特定条件(例如join条件包含了分片键),ShardingSphere-JDBC能够进行优化,从而减少跨分片查询次数。
  5. 分页优化

    • 对于带有LIMIT和OFFSET的分页查询,ShardingSphere-JDBC会对分页参数进行重置,以保证在分片环境下也能获取正确的分页结果,同时降低无效数据的传输。
  6. Hint机制

    • 用户可以通过SQL Hint直接指定查询的目标数据源或表,强制指定路由规则,这对于某些特殊场景下避免全表扫描或跨分片查询非常有用。

通过以上特性,ShardingSphere-JDBC能够帮助开发者在处理分片场景下的SQL查询时,有效提升查询效率并减少对多个表的重复查询。然而,值得注意的是,针对过于复杂的SQL语句和查询场景,仍需结合业务特点和数据分布进行合理的设计和优化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/524839.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【二分查找】Leetcode 搜索插入位置

题目解析 35. 搜索插入位置 这道题就是寻找target的目标位置&#xff0c;如果nums中包含target直接返回索引&#xff1b;如果不包含&#xff0c;需要返回target存放的合适位置 注意这道题有一个细节地方需要注意&#xff1a;如果现在target没有在nums中出现&#xff0c;并且目…

lua学习笔记9(字典的学习)

print("********************字典的学习***********************") a{["凌少"]"傻逼",["我"]"天才",["age"]24,["daihao"]114514,["8848"]20000} --访问单个变量 print(a["凌少"])…

华为海思2024春招数字芯片岗机试题(共9套)

huawei海思2024春招数字芯片岗机试题(共9套&#xff09;&#xff08;WX:didadidadidida313&#xff0c;加我备注&#xff1a;CSDN huawei数字题目&#xff0c;谢绝白嫖哈&#xff09; 题目包含数字集成电路、System Verilog、Verilog2001、半导体制造技术、高级ASIC芯片综合、…

finebi6.0中我的分析中...中加自己的菜单

js的两个扩展点是&#xff1a; BI.config("bi.result_wrapper", function (e) {return e.showMerge !0, e}),BI.config("bi.analysis.admin_list", function (e) {return e.showMergeUser !0, e}) 对应的组件在conf.min.js中的 bi.search_sort 点击事件…

pdf、docx、markdown、txt提取文档内容,可以应用于rag文档解析

返回的是文档解析分段内容组成的列表&#xff0c;分段内容默认chunk_size: int 250, chunk_overlap: int 50&#xff0c;250字分段&#xff0c;50分段处保留后面一段的前50字拼接即窗口包含下下一段前面50个字划分 from typing import Union, Listimport jieba import recla…

pycharm环境配置踩坑

一、新建目录 venv 二、创建本地解释器 3、配置国内镜像 1&#xff09;镜像源 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 华中理工大…

模块化——如何导入模块?(内置模块与自定义模块)

在Node.js中&#xff0c;要导入另一个模块&#xff0c;我们可以使用require函数。这个函数接受一个文件路径参数&#xff0c;并返回导入的模块。 一、require使用注意事项&#xff1a; (1)自己创建的模块&#xff0c;导入时建议写相对路径&#xff0c;不能省略./和../ //我把…

软件设计师:11-结构化开发与UML

结构化开发&#xff08;3-4分&#xff09; 一、模块化 二、耦合&#xff08;背&#xff09; 三、内聚&#xff08;背&#xff09; 四、设计原则&#xff08;背&#xff09; 五、系统文档 六、数据流图 数据流的起点或终点必须有一个是加工 判断依据&#xff1a; 1、…

centos安装使用elasticsearch

1.首先可以在 Elasticsearch 官网 Download Elasticsearch | Elastic 下载安装包 2. 在指定的位置(我的是/opt/zhong/)解压安装包 tar -zxvf elasticsearch-7.12.1-linux-x86_64.tar.gz 3.启动es-这种方式启动会将日志全部打印在当前页面&#xff0c;一旦使用 ctrlc退出就会导…

vue实现验证码验证登录

先看效果&#xff1a; 代码如下&#xff1a; <template><div class"container"><div style"width: 400px; padding: 30px; background-color: white; border-radius: 5px;"><div style"text-align: center; font-size: 20px; m…

IRIS / Chronicles 数据结构备忘录

数据结构的内容主要涉及到索引和全局变量。 这部分的内容的问题在于概念多&#xff0c;和普通的数据库对应的内容也不太一样&#xff0c;需要花点时间了解。 networked items 有关英文的解释是&#xff1a; Networked items that point to databases that use padded-string…

论文阅读AI工具链

文献检索 可以利用智谱清言来生成合适的文献检索式&#xff0c;并根据需要不断调整。 谷歌学术 在Google Scholar中进行检索时&#xff0c;您可以使用类似的逻辑来构建您的搜索式&#xff0c;但是语法会有所不同。Google Scholar的搜索框接受普通的文本搜索&#xff0c;但是…

力扣 583. 两个字符串的删除操作

题目来源&#xff1a;https://leetcode.cn/problems/delete-operation-for-two-strings/description/ C题解1&#xff1a;动态规划 寻找word1和word2拥有的公共最长子序列&#xff0c;之后分别对word1和word2进行删除操作&#xff0c;即可使word1和word2相等。 寻找公共最长子…

【学习】注意力机制(Attention)和 自注意力机制(self-Attention)

参考B站&#xff1a;09 Transformer 之什么是注意力机制&#xff08;Attention&#xff09; 1. 注意力机制&#xff08;Attention&#xff09; 红色的是科学家们发现&#xff0c;如果给你一张这个图&#xff0c;你眼睛的重点会聚焦在红色区域 人–》看脸 文章看标题 段落看…

HTTP 常见的状态码以及其适用场景

是什么 HTTP状态码&#xff08;英语&#xff1a;HTTP Status Code&#xff09;&#xff0c;用以表示网页服务器超文本传输协议响应状态的3位数字代码 它由 RFC 2616规范定义的&#xff0c;并得到 RFC 2518、RFC 2817、RFC 2295、RFC 2774与 RFC 4918等规范扩展 简单来讲&#…

【Linux ARM 裸机】开发环境搭建

1、Ubuntu 和 Windows 文件互传 使用过程中&#xff0c;要频繁进行 Ubuntu 和 Windows 的文件互传&#xff0c;需要使用 FTP 服务&#xff1b; 1.1、开启 Ubuntu 下的 FTP 服务 //安装 FTP 服务 sudo apt-get install vsftpd //修改配置文件 sudo vi /etc/vsftpd.conf//重启…

Redis数据库:高可用集群架构

目录 前言 一、Redis数据库高可用 二、Redis 主从复制 1、Redis主从复制概述 1.1 Redis主从复制概念 1.2 Redis主从复制的作用 1.3 Redis主从复制的流程 2、搭建Redis主从复制 2.1 环境部署 2.2 主服务器修改配置文件 2.3 从服务器修改配置文件 2.4 测试主从复制效…

解决方案AssertionError: Torch not compiled with CUDA enabled

文章目录 一、现象二、解决方案 一、现象 报错显示 s torch.from_numpy(padding_seq([s])).cuda().long() File "D:\Anaconda3\lib\site-packages\torch\cuda\__init__.py", line 221, in _lazy_initraise AssertionError("Torch not compiled with CUDA ena…

Linux -- 字符设备驱动--LED的驱动开发(初级框架)

驱动框架一阶段 我们怎样去点亮一个 LED 呢&#xff1f;分为三步&#xff1a; 看原理图确定引脚&#xff0c;确定引脚输出什么电平才能点亮/熄灭 LED 看主芯片手册&#xff0c;确定寄存器操作方法&#xff1a;哪些寄存器&#xff1f;哪些位&#xff1f;地址是&#xff1f; 编…

[数据结构]不带头单向非循环链表

我们有学过&#xff0c;顺序表如何制作&#xff0c;还有一个与其非常相似的结构就是链表的制作&#xff0c;不过链表在数据中的存储不像顺序表一样是按照内存的顺序进行存储的&#xff0c;其在内存中是一块一块的进行存储,具体如何我们可以看看下面这张图 此链表有一个头指针p…