首页 > 其他分享 >分库分表策略深入解析:基于范围(Range)、基于哈希(Hash)以及基于映射表(Mapping Table)

分库分表策略深入解析:基于范围(Range)、基于哈希(Hash)以及基于映射表(Mapping Table)

时间:2024-07-14 17:54:48浏览次数:16  
标签:基于 分库 Hash int userId public 分表 ID

目录

前言    

1. 基于范围的分库分表(Range)

2. 基于哈希的分库分表(Hash)

3. 基于映射表的分库分表(Mapping Table)



前言    

   分库分表是数据库优化中的一项重要技术,它通过将数据分散到多个数据库或表中,以提高系统的处理能力和响应速度。本篇将详细解析三种常见的分库分表策略:基于范围(Range)、基于哈希(Hash)以及基于映射表(Mapping Table),并提供Java代码示例。

1. 基于范围的分库分表(Range)

原理: 基于范围的分库分表策略是根据数据的一个特定属性(如时间戳、用户ID等)将其分配到不同的数据库或表中。例如,你可以根据用户的注册时间,将用户数据分配到不同的月份或年度数据库中。

代码示例: 下面代码展示如何根据用户ID的范围来确定数据应存储在哪一个分库中:

public class RangeShardingStrategy {
    // 分库数量
    private static final int SHARD_COUNT = 2;
    
    /**
     * 根据用户ID的范围确定分库编号。
     * @param userId 用户ID
     * @return 分库编号
     */
    public int getShardId(long userId) {
        // 假设每个分库处理50%的用户ID
        int shardId = (int)(userId % SHARD_COUNT);
        return shardId;
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        RangeShardingStrategy strategy = new RangeShardingStrategy();
        long userId = 12345L;
        int shardId = strategy.getShardId(userId);
        System.out.println("User ID " + userId + " will be stored in Shard " + shardId);
    }
}
2. 基于哈希的分库分表(Hash)

原理: 基于哈希的分库分表策略使用哈希函数将数据映射到特定的数据库或表中。这种策略的目的是确保数据在多个数据库或表之间均匀分布,从而达到负载均衡的效果。

代码示例: 下面代码示例展示如何使用MD5哈希函数将用户ID映射到分库中:

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class HashShardingStrategy {
    private static final int SHARD_COUNT = 2;
    
    /**
     * 使用MD5哈希函数将用户ID映射到分库编号。
     * @param userId 用户ID
     * @return 分库编号
     */
    public int getShardId(long userId) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] hashBytes = md.digest(Long.toString(userId).getBytes());
            int hashInt = ((hashBytes[3] & 0xFF) << 24) | ((hashBytes[2] & 0xFF) << 16) | ((hashBytes[1] & 0xFF) << 8) | (hashBytes[0] & 0xFF);
            return Math.abs(hashInt % SHARD_COUNT);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Error creating MD5 digest", e);
        }
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        HashShardingStrategy strategy = new HashShardingStrategy();
        long userId = 12345L;
        int shardId = strategy.getShardId(userId);
        System.out.println("User ID " + userId + " will be stored in Shard " + shardId);
    }
}
3. 基于映射表的分库分表(Mapping Table)

原理: 基于映射表的分库分表策略使用一个额外的表来记录数据与分库之间的映射关系。这种方法适用于数据分片规则复杂或需要动态调整分片规则的场景。

代码示例: 由于映射表通常存储在数据库中,下面示例将展示如何使用JDBC连接数据库并查询分库编号:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class MappingTableShardingStrategy {
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/sharding";
    private static final String USER = "root";
    private static final String PASSWORD = "password";
    
    /**
     * 从映射表中查找用户ID对应的分库编号。
     * @param userId 用户ID
     * @return 分库编号
     */
    public int getShardIdFromMapping(long userId) {
        int shardId = -1;
        try (Connection conn = DriverManager.getConnection(JDBC_URL, USER, PASSWORD)) {
            PreparedStatement stmt = conn.prepareStatement("SELECT shard_id FROM mapping_table WHERE user_id = ?");
            stmt.setLong(1, userId);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                shardId = rs.getInt("shard_id");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return shardId;
    }
}

// 使用示例
public class Main {
    public static void main(String[] args) {
        MappingTableShardingStrategy strategy = new MappingTableShardingStrategy();
        long userId = 12345L;
        int shardId = strategy.getShardIdFromMapping(userId);
        System.out.println("User ID " + userId + " will be stored in Shard " + shardId);
    }
}

标签:基于,分库,Hash,int,userId,public,分表,ID
From: https://blog.csdn.net/weixin_43298211/article/details/140354654

相关文章

  • Java笔记之HashMap
    HashMap的实现原理HashMap概述HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap底层就是一......
  • springboot 基于uni-app的蛋糕订购小程序的设计与实现
     #系统介绍相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低商家的运营人员成本,实现了蛋糕订购的标准化、制度化、程序化的管理,有效地防止了蛋糕订购的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正蛋糕信息、购物车、订单等信息。课题主要采......
  • 基于uniapp+springboot的记账小程序
    小程序视频链接:https://www.bilibili.com/video/BV1hi421Y7BE/?vd_source=cd3ceb58125e43fa5f95caf874aec5ef1.登录 2.注册 3.我的 4.账单 5.记账6.图表 7.明细 ......
  • springboot 基于uni-app的蛋糕订购小程序的设计与实现
    #系统介绍相比于以前的传统手工管理方式,智能化的管理方式可以大幅降低商家的运营人员成本,实现了蛋糕订购的标准化、制度化、程序化的管理,有效地防止了蛋糕订购的随意管理,提高了信息的处理速度和精确度,能够及时、准确地查询和修正蛋糕信息、购物车、订单等信息。课题主要采用......
  • 闲话:随机 Hash
    随机Hash:堆叠必要条件如果我们有一种方法来检验某个对象的某个性质,当对象满足这个性质的时候,这个方法必然能使该对象通过检验;否则这个方法会使该对象以\(p\)的概率通过检验。那么我们将得到一个极可能正确的检验方法:连续使用前述方法检验该对象足够多次。误通过检验的概率\(x......
  • 基于springboot+vue+uniapp的超市购物系统小程序
    开发语言:Java框架:springboot+uniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9系统展示商品管理公告管理公告类型管理摘要超市购物系统利用当下成熟完善的springboot框架,使用跨平台......
  • 基于springboot+vue+uniapp的校园失物招领系统
    开发语言:Java框架:springboot+uniappJDK版本:JDK1.8服务器:tomcat7数据库:mysql5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.3.9系统展示用户信息管理失物招领管理寻物启事管理论坛信息管理摘要校园失物招领系统使用Java语言进行......
  • 中移铁通智能插座:基于乐鑫 ESP8266 WiFi 芯片的可 DIY 智能插座(附源码)
    文末有视频演示第一部分1.简介中移铁通智能插座(型号:CMPOWERW1)基于乐鑫ESP8266WiFi芯片设计。由于早已没有官方APP支持,于是重新开发一版固件适配该硬件基本功能。固件基于乐鑫ESP8266_RTOS_SDK开发,通信协议采用MQTT-TCP方式控制插座的两个继电器。其......
  • 基于Ubuntu 24.04 LTS安装elasticsearch-8.14.3+Kibanna
    1.安装Elasticsearch1.1下载Elasticsearch#1.更新包索引sudoaptupdate#2.升级已安装的软件包sudoaptupgrade-y#3.进入/opt目录cd/opt#4.下载Elasticsearch压缩包sudowgethttps://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8......
  • 微信小程序源码-基于Java后端的医院体检管理系统毕业设计(附源码+论文)
    大家好!我是程序员一帆,感谢您阅读本文,欢迎一键三连哦。......