MySQL(106)如何設計分片鍵?

設計分片鍵(Sharding Key)是數據庫分片的核心,它決定了將數據分配到不同分片的方式。一個好的分片鍵應該能夠均衡地分布數據,避免熱點問題,提高查詢性能。下面將詳細介紹如何設計分片鍵,并結合代碼進行說明。

1. 選擇分片鍵的考慮因素

  1. 唯一性和可變性:分片鍵應該具有唯一性或較高的離散度,避免集中在某些分片。
  2. 查詢模式:根據查詢模式選擇合適的分片鍵,以優化查詢性能。
  3. 數據增長:考慮數據量的增長,分片鍵應能支持未來的數據擴展。
  4. 均勻分布:確保數據在各個分片中均勻分布,避免某個分片成為瓶頸。

2. 常見的分片鍵設計

  1. 基于唯一標識符(UUID):UUID可以確保數據均勻分布,但其長度較長,存儲空間較大。
  2. 基于哈希值:對某一字段(如用戶ID)進行哈希運算,將數據分配到不同的分片。
  3. 基于范圍:根據某一字段的值范圍分片,如日期范圍或地理位置范圍。
  4. 聯合分片鍵:多個字段聯合作為分片鍵,以提高均勻性和查詢性能。

3. 基于哈希值的分片鍵設計示例

我們以用戶ID為例,設計一個基于哈希值的分片鍵,并結合Spring Boot和Java代碼進行實現。

項目依賴

首先,確保在pom.xml中添加必要的依賴:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
</dependencies>
配置數據源

application.properties中配置多個數據源:

spring.datasource.primary.url=jdbc:mysql://localhost:3306/db_shard_0
spring.datasource.primary.username=root
spring.datasource.primary.password=password
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.secondary.url=jdbc:mysql://localhost:3306/db_shard_1
spring.datasource.secondary.username=root
spring.datasource.secondary.password=password
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
數據源配置類

使用Java代碼配置數據源:

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;@Configuration
public class DataSourceConfig {@Bean(name = "ds0")public DataSource dataSource0() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/db_shard_0").username("root").password("password").driverClassName("com.mysql.cj.jdbc.Driver").build();}@Bean(name = "ds1")public DataSource dataSource1() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/db_shard_1").username("root").password("password").driverClassName("com.mysql.cj.jdbc.Driver").build();}@Beanpublic DataSource routingDataSource(@Qualifier("ds0") DataSource ds0, @Qualifier("ds1") DataSource ds1) {AbstractRoutingDataSource routingDataSource = new AbstractRoutingDataSource() {@Overrideprotected Object determineCurrentLookupKey() {return ShardContextHolder.getShard(); // 從上下文中獲取當前分片鍵}};Map<Object, Object> targetDataSources = new HashMap<>();targetDataSources.put("ds0", ds0);targetDataSources.put("ds1", ds1);routingDataSource.setTargetDataSources(targetDataSources);routingDataSource.setDefaultTargetDataSource(ds0);return routingDataSource;}@Beanpublic JdbcTemplate jdbcTemplate(DataSource routingDataSource) {return new JdbcTemplate(routingDataSource);}
}
分片上下文

定義一個上下文來存儲當前的分片信息:

public class ShardContextHolder {private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();public static void setShard(String shard) {contextHolder.set(shard);}public static String getShard() {return contextHolder.get();}public static void clearShard() {contextHolder.remove();}
}
分片鍵設計和數據庫操作

實現基于哈希值的分片鍵,并進行數據庫操作:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;private String getShard(String userId) {int hash = userId.hashCode();int shardId = Math.abs(hash % 2); // 這里假設有2個分片return "ds" + shardId;}public void insertUser(String userId, String name, String email) {String shard = getShard(userId);ShardContextHolder.setShard(shard);String sql = "INSERT INTO users (user_id, name, email) VALUES (?, ?, ?)";jdbcTemplate.update(sql, userId, name, email);ShardContextHolder.clearShard();}public User getUser(String userId) {String shard = getShard(userId);ShardContextHolder.setShard(shard);String sql = "SELECT * FROM users WHERE user_id = ?";User user = jdbcTemplate.queryForObject(sql, new Object[]{userId}, (rs, rowNum) -> new User(rs.getString("user_id"), rs.getString("name"), rs.getString("email")));ShardContextHolder.clearShard();return user;}
}
測試

通過調用UserService中的方法進行測試:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class TestRunner implements CommandLineRunner {@Autowiredprivate UserService userService;@Overridepublic void run(String... args) throws Exception {userService.insertUser("user1", "Alice", "alice@example.com");userService.insertUser("user2", "Bob", "bob@example.com");User user1 = userService.getUser("user1");System.out.println(user1);User user2 = userService.getUser("user2");System.out.println(user2);}
}

結論

通過以上步驟,我們實現了基于哈希值的分片鍵設計。分片策略、數據源配置、分片上下文和數據庫操作的組合,使得系統可以根據特定的分片鍵將數據分布到不同的物理數據庫實例中,從而提升系統的性能和可擴展性。根據實際需求,還可以選擇其他分片策略(如范圍分片或列表分片)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/86935.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/86935.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/86935.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

汽車一鍵啟動升級手機控車

汽車一鍵啟動升級手機控車實現手機遠程啟動&#xff0c;不改變原車任何功能且全部免接線。升級后原車遙控器能在有效范圍內啟動車輛。移動管家手機控車一鍵啟動系統用手機遠程控制&#xff0c;完美兼容原車遙控器。支持長安、別克、寶馬、奧迪等眾多系列車型&#xff0c;市場99…

【開源項目】「安卓原生3D開源渲染引擎」:Sceneform?EQR

「安卓原生3D開源渲染引擎」&#xff1a;Sceneform?EQR 渲染引擎 “那一夜凌晨3點&#xff0c;第一次提交 PR 的手在抖……”——我深刻體會這種忐忑與激動。 倉庫地址&#xff1a;(https://github.com/eqgis/Sceneform-EQR)。 一、前言&#xff1a;開源對我意味著什么 DIY 的…

建造者模式 - Flutter中的樂高大師,優雅組裝復雜UI組件!

痛點場景&#xff1a;復雜的對話框配置 假設你需要創建一個多功能對話框&#xff1a; CustomDialog(title: 警告,content: 確定要刪除嗎&#xff1f;,titleStyle: TextStyle(fontSize: 20, color: Colors.red),contentStyle: TextStyle(fontSize: 16),backgroundColor: Color…

基于Java+Spring Boot的大學校園生活信息平臺

源碼編號&#xff1a;S559 源碼名稱&#xff1a;基于Spring Boot的大學校園生活信息平臺 用戶類型&#xff1a;雙角色&#xff0c;用戶、管理員 數據庫表數量&#xff1a;17 張表 主要技術&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven 運行環境&#xff1a;Wind…

C# .NET Framework 中的高效 MQTT 消息傳遞

介紹&#xff1a; 在當今互聯互通的世界里&#xff0c;設備之間高效可靠的通信至關重要。MQTT&#xff08;消息隊列遙測傳輸&#xff09;就是為此而設計的輕量級消息傳遞協議。本文將探討 MQTT 是什么、它的優勢以及如何在 .NET 框架中設置和實現它。最后&#xff0c;您將對 M…

nn.Embedding 和 word2vec 的區別

理解它們的關鍵在于??區分概念層級和職責??。 可以將它們類比為&#xff1a; ??word2vec&#xff1a;?? 一個??專門制作高質量詞向量模型的“工廠”??。??nn.Embedding&#xff1a;?? 一個??可存儲、查找并訓練詞向量的“智能儲物柜”??&#xff08;作為…

華為云Flexus+DeepSeek征文|??華為云ModelArts Studio大模型 + WPS:AI智能PPT生成解決方案?

引言&#xff1a;告別繁瑣PPT制作&#xff0c;AI賦能高效辦公 ?? 在商業匯報、學術研究、產品發布等場景中&#xff0c;制作專業PPT往往需要耗費大量時間進行內容整理、邏輯梳理和視覺美化。??華為云ModelArts Studio大模型??與??WPS??深度結合&#xff0c;推出AI-P…

【連接redis超時】

報錯 客戶端輸出緩沖區超限 Client … scheduled to be closed ASAP for overcoming of output buffer limits 表示這些客戶端&#xff08;通過 psubscribe 命令進行發布訂閱操作&#xff09;的輸出緩沖區超過了 Redis 配置的限制&#xff0c;Redis 會關閉這些客戶端連接來避免…

PHP「Not enough Memory」實戰排錯筆記

目錄 PHP「Not enough Memory」實戰排錯筆記 1. 背景 2. 快速定位 3. 為什么 5 MB 的圖片能耗盡 128 MB&#xff1f; 3.1 粗略估算公式&#xff08;GD&#xff09; 4. 實際峰值監控 5. 解決過程 6. 最佳實踐與防御措施 7. 總結 PHP「Not enough Memory」實戰排錯筆記 —…

Java垃圾回收機制和三色標記算法

一、對象內存回收 對于對象回收&#xff0c;需要先判斷垃圾對象&#xff0c;然后收集垃圾。 收集垃圾采用垃圾收集算法和垃圾收集器。 判斷垃圾對象&#xff0c;通常采用可達性分析算法。 引用計數法 每個對象設置一個引用計數器。每被引用一次&#xff0c;計數器就加1&am…

基于python網絡數據挖掘的二手房推薦系統

基于網絡數據挖掘的二手房推薦系統設計與實現 【摘要】 隨著互聯網技術在房地產行業的深入應用&#xff0c;線上房源信息呈爆炸式增長&#xff0c;給購房者帶來了信息過載的挑戰。為了提升二手房篩選的效率與精準度&#xff0c;本文設計并實現了一個基于網絡數據挖掘的二手房推…

Java + 阿里云 Gmsse 實現 SSL 國密通信

前言 解決接口或頁面僅密信瀏覽器&#xff08;或 360 國密瀏覽器&#xff09;能訪問的問題 測試頁面 測試網站-中國銀行&#xff1a;https://ebssec.boc.cn/boc15/help.html 使用其他瀏覽器&#xff08;google&#xff0c;edge等&#xff09;打開 使用密信瀏覽器打開 解決…

國產數據庫分類總結

文章目錄 一、華為系數據庫1. 華為 GaussDB 二、阿里系數據庫1. 阿里云 OceanBase2. PolarDB&#xff08;阿里云自研&#xff09; 三、騰訊系數據庫1. TDSQL&#xff08;騰訊云&#xff09;2. TBase&#xff08;PostgreSQL增強版&#xff09; 四、傳統國產數據庫1. 達夢數據庫&…

解密閉包:函數如何記住外部變量

&#x1f9e0; 什么是閉包&#xff1f; 閉包是一個函數對象&#xff0c;它不僅記住它的代碼邏輯&#xff0c;還記住了定義它時的自由變量&#xff08;即非全局也非局部&#xff0c;但被內部函數引用的變量&#xff09;。即使外部函數已經執行完畢&#xff0c;這些自由變量的值…

I2C協議詳解及STM32 HAL庫硬件I2C卡死問題分析

一、I2C協議詳解 1. I2C協議概述 Inter-Integrated Circuit (I2C) 是由 Philips 半導體&#xff08;現 NXP 半導體&#xff09;于 1980 年代設計的一種同步串行通信總線協議。該協議采用半雙工通信模式&#xff0c;支持多主從架構&#xff0c;專為短距離、低速率的芯片間通信…

HTTP協議-后端接收請求

起因就是不知道post這個請求體中這些格式有什么區別&#xff0c;后端又怎么去接收這些不同格式的內容 Get請求 get請求是比較簡單的一類 正常的直接用參數接收&#xff08;不寫的話名字要匹配&#xff09;或者RequestParam都可以接收&#xff0c;用對象綁定也可以 resultful…

HTML5 實現的圣誕主題網站源碼,使用了 HTML5 和 CSS3 技術,界面美觀、節日氛圍濃厚。

以下是一個 HTML5 實現的圣誕主題網站源碼&#xff0c;使用了 HTML5 和 CSS3 技術&#xff0c;界面美觀、節日氛圍濃厚。它包括&#xff1a; 圣誕樹動畫 &#x1f384;雪花飄落特效 ??圣誕祝福語 &#x1f381;響應式布局&#xff0c;適配移動端 你可以將代碼保存為 index.…

Spring Cloud Bus 和 Spring Cloud Stream

Spring Cloud Bus 和 Spring Cloud Stream 都是 Spring Cloud 生態中的消息通信組件&#xff0c;但它們的定位和使用場景有顯著區別&#xff1a; 1. Spring Cloud Bus 核心定位&#xff1a;分布式系統的消息廣播&#xff08;配置刷新、事件傳播&#xff09;。 典型場景&#x…

磁懸浮軸承位移信號的高精度估計:卡爾曼濾波算法深度解析

無需位移傳感器,濾波算法如何實現微米級精度? 磁懸浮軸承作為革命性的非接觸式支承技術,憑借無磨損、無需潤滑、高轉速等優勢,在飛輪儲能、高速電機、人工心臟泵和航空航天領域獲得了廣泛應用。其核心控制依賴于對轉子位移信號的高精度實時檢測,傳統電渦流傳感器雖能提供位…

DAY 43 預訓練模型

目錄 一、預訓練的概念 二、 經典的預訓練模型 2.1 CNN架構預訓練模型 2.2 Transformer類預訓練模型 2.3 自監督預訓練模型 三、常見的分類預訓練模型介紹 3.1 預訓練模型的發展史 3.2 預訓練模型的訓練策略 知識點回顧&#xff1a; 預訓練的概念常見的分類預訓練模型圖像…