当前位置: 首页 > news >正文

最佳实践 · MySQL 分区表实战指南

引言

在数据量急剧增长的今天,传统的数据库管理方式可能无法有效处理海量数据的存储和查询需求。MySQL 提供了分区表功能,这不仅能够帮助优化性能,还能简化数据管理过程。分区表允许将数据表拆分成多个逻辑上的分区,每个分区可以在物理上存储于不同的存储介质上,从而提升查询效率和数据处理速度。本文将深入探讨 MySQL 中四种主要的分区类型——范围分区(RANGE)、列表分区(LIST)、哈希分区(HASH)以及键分区(KEY),并通过实际的案例分析和示例数据,帮助你掌握如何使用这些分区技术来优化数据库性能,提升数据处理能力。

请在此添加图片描述

基础数据

为了制作一份满足上述内容的test表及数据,我们需要创建一个包含idhiredate字段的表,并插入一些示例数据。以下是具体的步骤:

创建表

CREATE TABLE test (id INT,hiredate DATETIME
);

插入数据

为了模拟大量数据,我们可以插入一些示例数据。以下是插入100万条数据的示例:

DELIMITER //CREATE PROCEDURE InsertTestData()
BEGINDECLARE i INT DEFAULT 1;WHILE i <= 1000000 DOINSERT INTO test (id, hiredate) VALUES (i, NOW() - INTERVAL FLOOR(RAND() * 3650) DAY);SET i = i + 1;END WHILE;
END //DELIMITER ;CALL InsertTestData();

这个存储过程会插入100万条数据,每条数据的hiredate字段是一个随机日期,范围从当前日期往前推10年。

RANGE 分区

概述

RANGE 分区基于列值的连续区间将数据分配到不同的分区。这种分区类型特别适用于时间或日期字段,可以有效地管理和清理历史数据。

请在此添加图片描述

工作原理

RANGE 分区依据列值的范围来决定记录所属的分区。例如,可以根据日期字段的值,将数据按月、按季度或按年分配到不同的分区中。这样一来,查询和删除某一时间段的数据时,只需操作相关的分区,从而提高性能和减少锁竞争。

假设有一个员工表,我们希望根据雇佣日期对数据进行分区,以便高效清理过期数据:

CREATE TABLE my_range_datetime (id INT,hiredate DATETIME
)
PARTITION BY RANGE (TO_DAYS(hiredate)) (PARTITION p1 VALUES LESS THAN (TO_DAYS('2017-12-02')),PARTITION p2 VALUES LESS THAN (TO_DAYS('2017-12-03')),PARTITION p3 VALUES LESS THAN (TO_DAYS('2017-12-04')),PARTITION p4 VALUES LESS THAN (TO_DAYS('2017-12-05')),PARTITION p5 VALUES LESS THAN (TO_DAYS('2017-12-06')),PARTITION p6 VALUES LESS THAN (TO_DAYS('2017-12-07')),PARTITION p7 VALUES LESS THAN (TO_DAYS('2017-12-08')),PARTITION p8 VALUES LESS THAN (TO_DAYS('2017-12-09')),PARTITION p9 VALUES LESS THAN (TO_DAYS('2017-12-10')),PARTITION p10 VALUES LESS THAN (TO_DAYS('2017-12-11')),PARTITION p11 VALUES LESS THAN (MAXVALUE)
);

在上面的示例中,p11 是一个默认分区,用于存储所有大于指定日期的记录。TO_DAYS() 函数将日期转换为天数,从而实现分区。

mysql> insert into my_range_datetime select * from test;
Query OK, 7240 rows affected
Records: 7240  Duplicates: 0  Warnings: 0mysql> explain 
select * from my_range_datetime where hiredate >= '2017-12-07 12:45:03' and hiredate<='2017-12-10 11:12:30'; 
+----+-------------+-------------------+--------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table             | partitions   | type | possible_keys | key  | key_len | ref  | rows | filtered | Extra       |
+----+-------------+-------------------+--------------+------+---------------+------+---------+------+------+----------+-------------+
|  1 | SIMPLE      | my_range_datetime | p7,p8,p9,p10 | ALL  | NULL          | NULL | NULL    | NULL |   11 |    11.11 | Using where |
+----+-------------+-------------------+--------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set

请注意执行计划中partitions部分的内容,仅查询了p7、p8、p9和p10这四个分区。由此可见,使用to_days函数确实能够实现分区裁剪。

上述示例是基于datetime类型的,那么对于timestamp类型,我们是否也会遇到类似的问题呢?

接下来,我们将测试一下基于UNIX_TIMESTAMP函数的RANGE分区方案,以验证其是否能够实现分区裁剪。

针对TIMESTAMP类型的分区方案

注意:对于 TIMESTAMP 类型字段,使用 UNIX_TIMESTAMP 函数来实现类似的分区:

CREATE TABLE my_range_timestamp (id INT,hiredate TIMESTAMP
)
PARTITION BY RANGE (UNIX_TIMESTAMP(hiredate)) (PARTITION p1 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-02 00:00:00')),PARTITION p2 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-03 00:00:00')),PARTITION p3 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-04 00:00:00')),PARTITION p4 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-05 00:00:00')),PARTITION p5 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-06 00:00:00')),PARTITION p6 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-07 00:00:00')),PARTITION p7 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-08 00:00:00')),PARTITION p8 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-09 00:00:00')),PARTITION p9 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-10 00:00:00')),PARTITION p10 VALUES LESS THAN (UNIX_TIMESTAMP('2017-12-11 00:00:00')),PARTITION p11 VALUES LESS THAN (MAXVALUE) 
);

请在此添加图片描述

同样地,该方案也能实现分区裁剪。

在MySQL 5.7版本之前,针对DATE和DATETIME类型的列,要实现分区裁剪,我们只能依赖于YEAR()和TO_DAYS()函数。然而,在MySQL 5.7版本中,引入了一个新的函数——TO_SECONDS(),为分区裁剪提供了更多的选择。

LIST 分区

概述

LIST 分区用于将数据分配到不同的分区,依据的是离散的枚举值列表。与 RANGE 分区不同,LIST 分区适合处理那些不连续的值,例如状态码、地区码等。

工作原理

LIST 分区通过枚举所有可能的值,并将它们映射到特定的分区中。这样,在插入数据时,系统可以根据列值快速确定数据应放置在哪个分区。

如果我们有一个表保存订单的状态信息,可以使用 LIST 分区来高效地管理不同状态的订单:

CREATE TABLE orders (id INT,status INT
)
PARTITION BY LIST (status) (PARTITION p0 VALUES IN (0, 1, 2),    -- 代表未处理和处理中状态PARTITION p1 VALUES IN (3, 4, 5)     -- 代表已完成和已取消状态
);

注意:LIST 分区列最好是非 NULL 列,否则在插入数据时可能会出现错误。

HASH 分区

概述

HASH 分区通过对指定列的哈希值进行分区,适用于没有明确分区字段的数据表。HASH 分区确保数据均匀分布在各个分区中。

工作原理

HASH 分区对指定列的值进行哈希计算,然后根据计算结果将数据分配到不同的分区。由于哈希函数的性质,这种分区方式可以较好地实现数据均匀分布。

对于没有明显分区字段的用户表,可以使用 HASH 分区:

CREATE TABLE users (id INT NOT NULL,name VARCHAR(50),registration_date DATE
)
PARTITION BY HASH(id)
PARTITIONS 4;

在这个例子中,数据根据 id 列的哈希值分配到 4 个分区中。

LINEAR HASH 分区

概述

LINEAR HASH 分区是 HASH 分区的一种变体,通过线性哈希算法来进行分区。它适合大数据量的场景,例如 TB 级的数据表。

工作原理

与传统的 HASH 分区不同,LINEAR HASH 分区使用线性哈希算法进行分区,这可以使得在数据增长时,增加、删除、合并和拆分分区的操作更为高效。然而,这也可能导致数据分布不均匀的情况。

对于大规模的数据表,使用 LINEAR HASH 分区可以优化分区操作:

CREATE TABLE large_table (id INT NOT NULL,data VARCHAR(100)
)
PARTITION BY LINEAR HASH(id)
PARTITIONS 4;

KEY 分区

概述

KEY 分区与 HASH 分区类似,但允许使用多个列作为分区键,并基于列的 MD5 值进行分区。适用于分区键需要多个列的情况。

工作原理

KEY 分区通过计算列值的 MD5 值并对其进行分区,可以将数据均匀地分配到不同的分区中。它支持对多个列进行分区,但要求列值必须是整数或可以转换为整数的类型。

如果我们希望将数据按多个列的值进行分区,可以使用 KEY 分区:

CREATE TABLE multi_key_table (id INT NOT NULL PRIMARY KEY,name VARCHAR(50),category INT
)
PARTITION BY KEY (id, category)
PARTITIONS 4;

如果表中有主键或唯一键,KEY 分区默认使用这些键进行分区。如果没有,则需要显式指定分区列。

小结

  • RANGE 分区适用于具有连续区间的字段,如日期或时间,可以显著提高数据管理效率。
  • LIST 分区适用于离散值的场景,如状态码或地区码,适合处理特定的枚举值。
  • HASH 分区适用于没有明显分区特征的数据表,确保数据均匀分布。
  • LINEAR HASH 分区在大数据量场景下优化分区操作,但可能导致数据分布不均。
  • KEY 分区允许使用多个列作为分区键,基于列的 MD5 值进行分区,适合复杂的分区需求。

每种分区类型的选择应根据数据特征和应用需求来决定,以实现最佳的性能和管理效果。

结尾

通过对 MySQL 分区表的了解,我们可以看到,合理利用分区技术能够显著提升数据管理的效率和查询性能。无论是需要按照时间段清理历史数据,还是希望将数据分散到多个分区以加快检索速度,MySQL 的分区机制都能为复杂的数据场景提供有效的解决方案。在实际应用中,选择合适的分区类型并根据业务需求调整分区策略,将帮助我们在面对海量数据时保持系统的高效稳定。希望本文提供的实用示例和最佳实践,能够为数据库管理的道路上提供价值。

相关文章:

最佳实践 · MySQL 分区表实战指南

引言 在数据量急剧增长的今天&#xff0c;传统的数据库管理方式可能无法有效处理海量数据的存储和查询需求。MySQL 提供了分区表功能&#xff0c;这不仅能够帮助优化性能&#xff0c;还能简化数据管理过程。分区表允许将数据表拆分成多个逻辑上的分区&#xff0c;每个分区可以…...

详细介绍 Redis 列表的应用场景

Redis 的列表&#xff08;List&#xff09;数据类型有以下一些主要应用场景&#xff1a; 一、消息队列 生产者-消费者模式 生产者可以使用LPUSH命令将消息从列表的左端&#xff08;头部&#xff09;插入到 Redis 列表中。消费者则使用BRPOP或RPOP命令从列表的右端&#xff08;…...

游戏如何检测加速外挂

在游戏面临的众多外挂风险中&#xff0c;除了常见的内存修改挂、注入挂等作弊手段&#xff0c;黑灰产还常用「加速」手段实现作弊。 游戏安全风险分布占比图 「加速」顾名思义是指改变游戏内的速度。游戏在运行中需要以帧为单位播放画面&#xff0c;而计算每帧动画播放所需时间…...

【STM32 HAL库】OLED显示模块

【STM32 HAL库】OLED显示模块 前言理论OLED基本参数OLED基本驱动原理OLED坐标轴 应用CubeMx配置底层函数代码高层封装函数printf显示函数 前言 本文为笔者学习 OLED 的总结&#xff0c;基于keysking的视频内容&#xff0c;如有错误&#xff0c;欢迎指正 理论 OLED基本参数 …...

Redis---卸载Redis

简介 在Linux系统或者Mac系统卸载Redis。 步骤 1、停止Redis服务 #查看Redis服务进行 ps -ef | grep redis #停止Redis服务 redis-cli -a 111111 -p 6370 shutdown #再次查看Redis服务进程 ps -ef | grep redis2、删除/usr/local/bin目录下与Redis相关的文件 #查找Redis相…...

《C++模板元编程实战》阅读记录

目录 写在前面基本介绍第一部分 元编程基础技术第1章 基本技巧1.1元函数与type_traits1.1.1 元函数介绍 写在前面 这本书之前是在一片公众号里面介绍的&#xff0c;我觉的不错&#xff0c;想着提高一下自己C的水平&#xff0c;就买了一本&#xff0c;大概是2022年下半年买的&a…...

pybind11 学习笔记

pybind11 学习笔记 0. 一个例子1. 官方文档1.1 Installing the Library1.1.1 Include as A Submodule1.1.2 Include with PyPI1.1.3 Include with Conda-forge 1.2 First Steps1.2.1 Separate Files1.2.2 PYBIND11_MODULE() 宏1.2.3 example.cpython-38-x86_64-linux-gnu.so 的…...

36.贪心算法3

1.坏了的计算器&#xff08;medium&#xff09; . - 力扣&#xff08;LeetCode&#xff09; 题目解析 算法原理 代码 class Solution {public int brokenCalc(int startValue, int target) {// 正难则反 贪⼼int ret 0;while (target > startValue) {if (target % 2 0…...

htop(1) command

文章目录 1.简介2.格式3.选项4.交互式命令5.示例6.小结参考文献 1.简介 htop 是一种交互式、跨平台的基于 ncurses 的进程查看器。 类似于 top&#xff0c;但 htop 允许您垂直和水平滚动&#xff0c;并使用指向设备(鼠标)进行交互。您可以观察系统上运行的所有进程&#xff0…...

ODrive学习——添加485编码器支持

系列文章目录 文章目录 系列文章目录前言一、端口处理二、在Encoder中引入新的类型1.增加485类型2.增加串口的初始化操作3.数据处理 总结 前言 尝试在ODrive中添加485型的编码器的支持 一、端口处理 计划使用PA2及PA3作为485通信的端口。这样首先要把外部温度传感器的I/O口给…...

在OSX上: 使用brew安装nginx 后,在通过编译安装第三方模块

1. 下载nginx安装包nginx: download 2. mac环境编译源码需要安装pcre、openssl等第三方依赖&#xff0c;可参考在OSX上: 使用brew安装nginx 后&#xff0c;在通过编译安装第三方模块 - ZhYQ_note - 博客园 3. nginx可支持的配置参考Building nginx from Sources 4. 执行 ./…...

C++初阶学习第六弹------标准库中的string类

目录 一.标准库中的string类 二.string的常用接口函数 2.1string类对象的构造 2.2 string的容量操作 2.3 string类的访问与遍历 2.4 string类对象的修改 2.5 string类常用的非成员函数 三、总结 一.标准库中的string类 可以简单理解成把string类理解为变长的字符数组&#x…...

Linux基础-Makefile的编写、以及编写第一个Linux程序:进度条(模拟在 方便下载的同时,更新图形化界面)

目录 一、Linux项目自动化构建工具-make/Makefile ​编辑 背景&#xff1a; makefile小技巧&#xff1a; 二、Linux第一个小程序&#xff0d;进度条 先导&#xff1a; 1.如何利用/r,fflush(stdout)来实现我们想要的效果&#xff1b; 2.写一个倒计时&#xff1a; 进度条…...

华为云DevSecOps和DevOps

目录 1.华为云DevSecOps和DevOps 1.1 DevSecOps 1.1.1 核心功能 1.1.2 优势 1.2 DevOps 1.2.1 核心功能 1.2.2 优势 1.3 DevOps和DevSecOps的区别 1.3.1 安全性集成 1.3.2 自动化的安全工具 1.3.3 团队协作 1.3.4 质量与合规性 1.3.5 成本与风险管理 1.3.5 总结 …...

RESTful API设计中的GET与POST:何时及为何成为首选?

RESTful API设计中的GET与POST&#xff1a;何时及为何成为首选&#xff1f; 在RESTful API的设计过程中&#xff0c;HTTP方法&#xff08;GET、POST、PUT、DELETE等&#xff09;作为资源的操作标识&#xff0c;扮演着至关重要的角色。然而&#xff0c;在实际开发中&#xff0c…...

秋招自我介绍

1min 尊敬的面试官您好&#xff0c;感谢您百忙之中参加我的面试。我是来自北京大学的王峰。 在实习经历方面&#xff0c;我曾在美团和小米公司实习。在美团主要负责核身、质检、词云项目。 在核身项目中&#xff0c;完整的经历从0-1的项目上线过程 在质检项目中&#xff0c;进…...

html加载页面

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>算数模一体化</title> </head><b…...

【数据可视化】Arcgis api4.x 热力图、时间动态热力图、timeSlider时间滑块控件应用 (超详细、附免费教学数据、收藏!)

1.效果 目录 1.效果 2.安装配置 3.热力图 4.TimeSlider滑块应用 4.1 时间滑块控件 4.2 添加控件 5.时间动态热力图 2.安装配置 这里不教大家如何在前端框架使用arcgis api。不过npm安装、css如何引入、教学数据存放与图层加载的教程&#xff0c;可以浏览我之前发的一篇文…...

WEB攻防-JavaWweb项目JWT身份攻击组件安全访问控制

知识点&#xff1a; 1、JavaWeb常见安全及代码逻辑&#xff1b; 2、目录遍历&身份验证&逻辑&JWT&#xff1b; 3、访问控制&安全组件&越权&三方组件&#xff1b; 演示案例&#xff1a; JavaWeb-WebGoat8靶场搭建使用 安全问题-目录遍历&身份认…...

【C++算法】模拟算法

替换所有的问号 题目链接 替换所有的问号https://leetcode.cn/problems/replace-all-s-to-avoid-consecutive-repeating-characters/description/ 算法原理 代码步骤 class Solution { public:string modifyString(string s) {int n s.size();for(int i 0; i < n; i){…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

基础测试工具使用经验

背景 vtune&#xff0c;perf, nsight system等基础测试工具&#xff0c;都是用过的&#xff0c;但是没有记录&#xff0c;都逐渐忘了。所以写这篇博客总结记录一下&#xff0c;只要以后发现新的用法&#xff0c;就记得来编辑补充一下 perf 比较基础的用法&#xff1a; 先改这…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...