初探Sharding-JDBC订单表分片实现

news2025/1/19 20:15:00

设计订单系统有两个数据库db_order_01和db_order_02。每个数据库分别有t_order_0和t_order_1两张订单表。

订单表设计有订单ID(order_id),用户ID(user_id),商户ID(merchant_id)。假设商户查看订单操作要比用户查看订单的操作更加频繁。避免商户查询订单时跨库查询,用商户ID对数据库数量取模的方式将同一个商户的订单路由到同一个数据库中。通过对用户ID进行Hash后取模,将同一个用户的订单路由到同一张表中。以上设计主要是为了使用取模算法和哈希取模算法😁。

订单数据库和表创建DDL: t_order.sql

一、ShardingSphereDataSource数据源配置

使用的Spring boot、ShardingSphere-JDBC和MyBatis的依赖如下:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.6.8</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.apache.shardingsphere</groupId>
                <artifactId>shardingsphere-jdbc-core</artifactId>
                <version>5.2.0</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>2.2.2</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

(1)创建db_order_01和db_order_02数据源

    /**
     * HikariConfig
     * @param database db
     * @return dataSource config
     */
    private HikariConfig create(String database) {
        Assert.hasLength(database, "database require not null");
        HikariConfig config = new HikariConfig();
        config.setUsername(USERNAME);
        config.setPassword(PASSWORD);
        config.setDriverClassName(DRIVER_NAME);
        config.setJdbcUrl(String.format("jdbc:mysql://localhost:3306/%s", database));
        return config;
    }

    /**
     * create DataSource
     * @param database db
     * @return dataSource
     */
    private DataSource createDataSource(String database) {
        return new HikariDataSource(this.create(database));
    }

    @Bean
    public DataSource dbOrder01DataSource() {
        return this.createDataSource("db_order_01");
    }

    @Bean
    public DataSource dbOrder02DataSource() {
        return new HikariDataSource(this.create("db_order_02"));
    }

(2)初始化数据源集合

   /**
     * 初始化数据源
     * @return dataSource map
     */
    private Map<String, DataSource> initDataSourceMap() {
        Map<String, DataSource> dataSourceMap = new HashMap<>();
        // order databases
        dataSourceMap.put("db_order_0", this.dbOrder01DataSource());
        dataSourceMap.put("db_order_1", this.dbOrder02DataSource());
       
        return dataSourceMap;
    }

请注意数据源集合中database的key,该key在后面的表分片规则时指定实际数据节点时需要使用。

(3)配置分片规则并创建ShardingSphereDataSource

    @Bean
    @Primary
    public DataSource shardingDateSource() {
        // 分片规则集
        List<RuleConfiguration> dbRules = new ArrayList<>();
        ShardingRuleConfiguration shardingRule = new ShardingRuleConfiguration();
        // 设置默认的分片键,同一个商户的订单放到一个数据库中
        String defaultShardingColumn = "merchant_id";
        shardingRule.setDefaultShardingColumn(defaultShardingColumn);
        // 创建默认database分片策略
        shardingRule.setDefaultDatabaseShardingStrategy(this.createStandardShardingStrategy(
                defaultShardingColumn, "MOD"));
        // 创建默认的表分片策略,同一个用户的订单放到一张表中
        String userIdShardingColumn = "user_id";
        shardingRule.setDefaultTableShardingStrategy(this.createStandardShardingStrategy(
                userIdShardingColumn, "HASH_MOD"));
        // 分片算法properties属性配置
        Map<String, AlgorithmConfiguration> shardingAlgorithmsConf = shardingRule.getShardingAlgorithms();
        // 设置分片算法属性配置
        shardingAlgorithmsConf.putAll(this.shardingAlgoConfig());
        // key gen算法属性配置
        Map<String, AlgorithmConfiguration> keyGenerators = shardingRule.getKeyGenerators();
        keyGenerators.putAll(this.keyGenAlgoConfig());
        // order table sharding 配置
        ShardingTableRuleConfiguration orderTableRule = new ShardingTableRuleConfiguration(
                "t_order", "db_order_$->{0..1}.t_order_$->{0..1}");
        // order_id gen
        KeyGenerateStrategyConfiguration orderIdGen =
                new KeyGenerateStrategyConfiguration("order_id", "SNOWFLAKE");
        orderTableRule.setKeyGenerateStrategy(orderIdGen);
        List<ShardingTableRuleConfiguration> tableRuleConfigs = new ArrayList<>();
        // add t_order rule
        tableRuleConfigs.add(orderTableRule);
        // config t_user table sharding rule
        ShardingTableRuleConfiguration tUserTableShardingRule = this.configUserTableShardingRule();
        // add t_user rule
        tableRuleConfigs.add(tUserTableShardingRule);
        // set tables rule
        shardingRule.getTables().addAll(tableRuleConfigs);
        dbRules.add(shardingRule);
        DataSource primaryDataSource = null;
        try {
            ModeConfiguration modeConfiguration = this.createModeConfiguration();
            primaryDataSource = ShardingSphereDataSourceFactory.createDataSource(modeConfiguration,
                    this.initDataSourceMap(), dbRules, this.shadingDataSourceProps());
        } catch (SQLException e) {
            LOGGER.error("create primaryDataSource error:", e);
        }
        return Objects.requireNonNull(primaryDataSource, "primaryDataSource require not null");
    }

配置表分片规则(ShardingTableRuleConfiguration)时,存在多个数据源和多个表分片时,可以使用Groovy表达式。简单配置示例如下:

 

注意actualDataNodes的配置,如果配置不正确,在执行SQL时会出现找不到路由数据源的异常。 

 二、执行测试并验证

其中MyBatis的配置这里就不就行介绍了。源码地址: https://gitee.com/qinshizhang/shard-jdbc

下载后简单配置一个数据库信息即可启动并运行。

(1)测试新增订单数据 

    @Test
    void insertSelective() {
        this.checkMapper();
        OrderEntity order = new OrderEntity();
        order.setUserId(userIdAlgo.generate());
        order.setMerchantId(localRandom.nextLong(47));
        order.setOrderId((Long) orderIdGenAlgo.generateKey());
        int insertRows = orderMapper.insertSelective(order);
        assertEquals(1, insertRows);
    }

测试执行结果如下: 

 其中商户ID=6,对2取模结果为0,数据路由到db_order_0数据库中。用户ID是468323156650622977,该值hash对2取模结果为1,数据路由到t_order_1表中。

到此,第一个使用ShardingSphere-JDBC进行订单数据进行分库分表的示例完成了,后续逐渐加入用户、产品、库存等表的操作。🤠🤠🤠一起加入学习吧!!🤠🤠🤠

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NLP学习笔记五-simple RNN

NLP学习笔记五-simple RNN 我这个学习笔记&#xff0c;感兴趣的小伙伴&#xff0c;看的时候尽量从头开始看&#xff0c;这样更好理解&#xff0c;也更有收获。 simple RNN的单元结构图如下&#xff1a; 其中A就是我们需要学习的参数矩阵&#xff0c; h t − 1 h_{t-1} ht−1​…

【MySQL数据库 | 第十五篇】事务

目录 前言&#xff1a; 介绍事务&#xff1a; 控制事务&#xff1a; 事务四大特性&#xff1a; 并发事务问题&#xff1a; 事务隔离级别&#xff1a; 总结: 前言&#xff1a; 这章我们将进入到MySQL基础篇的最后一章&#xff1a;事务&#xff0c;希望大家可以坚持下去&#xf…

车间如何做好“生产计划”,打造高效运营的智能工厂

新形势下&#xff0c;面对外部不断变化的市场需求、供应链下游企业管理升级需求以及持续上涨的人力成本&#xff0c;传统工厂模式必须要变革才能更好地发展。热潮之下&#xff0c;企业纷纷规划建设智能工厂。那么&#xff0c;新工厂规划如何避免投入浪费&#xff0c;少走弯路&a…

Linux——进程间通信,信号量的使用+小demo(C语言)

一.什么是信号量呢&#xff1f;用途又是什么呢&#xff1f; 信号量就是解决进程之间竞争资源的情况&#xff0c;比如&#xff1a;我们在宿舍用的公共洗衣机&#xff0c;我们只有当它空闲的时候&#xff0c;我们才可以去使用它&#xff0c;当别人看到洗衣机在使用的时候&#xf…

LVS负载均衡群集部署(DR模式)

一.DR模式 LVS负载均衡群集部署 ipvsadm 工具选项说明&#xff1a; 工具选项作用-A添加虚拟服务器-D删除整个虚拟服务器-s指定负载调度算法&#xff08;轮询&#xff1a;rr、加权轮询&#xff1a;wrr、最少连接&#xff1a;lc、加权最少连接&#xff1a;wlc&#xff09;-a表示…

clickhouse-MergeTree

创建建表语句 create table t_order_mt(id UInt32,sku_id String,total_amount Decimal(16,2),create_time Datetime ) engine MergeTreepartition by toYYYYMMDD(create_time)primary key (id)order by (id,sku_id); 插入测试数据 insert into t_order_mt(id,sku_id,total_…

chatgpt赋能python:Python数据分析必备工具:Pandas

Python数据分析必备工具&#xff1a;Pandas Python作为一门流行的编程语言&#xff0c;广泛应用于数据科学领域。而Pandas作为Python语言下的数据分析库&#xff0c;被广泛地应用于数据处理、数据分析、数据可视化等方面。本文将介绍如何快速地入门Pandas并进行数据分析。 什…

《统计学习方法》——逻辑斯谛回归与最大熵模型(下)

最大熵模型 极大似然估计 下面证明对偶函数的极大化等价于最大熵模型的极大似然估计。 极大似然估计的思想就是通过概率最大化来求出最符合的分类。对应的步骤为&#xff1a; 根据训练集&#xff0c;写出不同分类下的概率函数将不同分类下的概率函数进行汇总&#xff0c;写…

[hsctf 2023] crypto,pwn,rev部分

刚完了天津又来个衡水,这个大部分题比较简单,最后两天整了3个crypto有点意思. crypto double-trouble 给了密文 Hvwg gvcizr bch ps hcc vofr. Wb toqh, W kwzz uwjs wh hc mci fwuvh bck! Hvs tzou wg hvs tczzckwbu: OmqemdOubtqdeMdqOaax Vcksjsf, wh wg sbqcrsr gc mci …

刷脸登录(人工智能)

刷脸登录 理解刷脸登录的需求 理解刷脸登录的开发流程实现刷脸登录功能 浅谈人工智能 人工智能的概述 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门…

chatgpt赋能python:Python怎么下pip:简单又方便的工具

Python怎么下pip&#xff1a;简单又方便的工具 Python 是一门广泛应用的高级编程语言&#xff0c;它设计的初衷是让程序员更加愉悦地编写代码&#xff0c;同时提供了多种强大的库和框架。其中&#xff0c;pip 是最为常见的第三方包管理工具&#xff0c;本文将为你介绍如何下载…

uniapp实现主题切换功能实现第一种方式(scss变量+vuex)

随着用户端体验的不断提升&#xff0c;很多应用在上线的时候都要求做不同的主题&#xff0c;最基本的就是白天与夜间主题。 就像b站app主题切换&#xff0c;像这样的 uniapp因为能轻松实现多端发布而得到很多开发者的青睐&#xff0c;但每个端的实现也有可能不同&#xff0c;现…

NLP学习笔记四-word embeding

NLP学习笔记四-word embeding word embeding就是一块重头戏了&#xff0c;因为这里做完&#xff0c;我们的数据处理部分也基本上收尾了。 下面我们附上一张图&#xff1a; 如上图&#xff0c;word embeding实在我们one-hot word之后才可以进行的&#xff0c;每一步处理技术都是…

NVM安装(管理Node.js版本)

NVM可以在一台电脑上安装多个版本Node.js&#xff0c;并且可以一条指令随时下载或切换版本 下载安装 github下载地址&#xff1a;https://github.com/coreybutler/nvm-windows/releases 一路next&#xff0c;注意修改安装路径即可&#xff08;不要安装在有中文名称的目录下&am…

Latex图表制作:关于EPS文件转PDF文件及PDF裁剪自动化的Shell脚本制作

关于EPS文件转PDF文件及PDF裁剪自动化的Shell脚本制作 前言一、EPS文件转PDF文件1. 过去的科研绘图方案2. 未来的科研绘图方案 二、使用步骤1. 单例操作a. 安装epstoolb. 切除EPS文件白边并保存临时EPS文件d. 将EPS文件转换为PDF文件 2. 批处理操作a. Shell 脚本b. 使用说明 参…

贝叶斯公式的理解与推导(简单版本)

院子里面有条狗&#xff0c;过去几十年中&#xff0c;平均100天狗会叫50天&#xff0c;平均100天被偷盗一次&#xff0c;偷盗时有90%概率狗会叫&#xff0c;请问当狗叫的时候&#xff0c;是小偷入侵的概率有多大&#xff1f; 分析&#xff1a; 狗叫为独立事件A&#xff0c;偷盗…

chatgpt赋能python:Python如何将PDF转换为Word文档

Python如何将PDF转换为Word文档 在现代电脑使用的日常工作中&#xff0c;PDF格式的文档已经变得很普遍。这种文件格式十分方便&#xff0c;但是有时候可能需要将PDF文件转换为Word文档。幸运的是&#xff0c;Python提供了多种方法来实现这个目标。 为什么要将PDF转换为Word&a…

6. 常见的文件编码方式及查看网页源码的编码方式

6. 常见的文件编码方式及查看网页源码的编码方式 文章目录 6. 常见的文件编码方式及查看网页源码的编码方式1. 编码的由来2. 编码的作用3. 常见的编码方式4. ASCII码5. Unicode符号集6. UTF-87. GB23128. GBK9. ISO-8859-110. 文件编码查看方式11. 网页编码查看方式12. 留言 1.…

【学习日记2023.6.9】之 SpringCloud入门

文章目录 SpringCloud1. 认识微服务1.1 单体架构1.2 分布式架构1.3 微服务1.4 SpringCloud1.5 总结 2. 服务拆分和远程调用2.1 服务拆分原则2.2 服务拆分示例2.2.1 导入Sql语句2.2.2 导入demo工程 2.3 实现远程调用案例2.3.1 案例需求&#xff1a;2.3.2 注册RestTemplate2.3.3 …

计算机组成原理——总线,输入输出系统

文章目录 **一 总线概述****1 总线基本概念****1.1 定义****1.2 总线设备****1.3 总线特性** **2 总线的分类****2.1 片内总线****2.2 系统总线****2.3 I/O总线****2.4 通信总线** **3 系统总线的结构****3.1 单总线结构****3.2 双总线结构****3.3 三总线结构** **4 常见的总线…