【数据库系列】MQSQL历史数据分区

news2024/12/23 22:52:58

互联网行业企业都倾向于mysql数据库,虽说mysql单表能支持亿级别的数据量,加上索引优化下查询速度,勉强能使用,但是对于追求性能和效率的互联网企业,这是远远不够的。Mysql数据库单表数据量到达500万左右,达到性能最佳点,可是对于需要亿级别的业务来说,500万是远远不够的。既然数据放在一个位置不行,那我们就把数据拆分放到多个位置。如果寻找数据位置的时间成本忽略不计的话,那么在亿级别的数据量里面查询数据的时间成本就相当于从单张表力查询数据的时间成本一样。这就是分库分表的最初思想。

对表进行分区,是为了能最大限度的提高数据库的IO能力,分区能让数据库将同一张表中的数据放在不同的磁盘下,提高数据库IO能力,类似多核多线程的思想。因此分区能提高单标的高并发能力。

range分区

range方式创建分区语句如下:

#根据表结构中的时间字段来作为分区键,如下的year()方法,或者to_char()方法
 
create table table_range(
 
     id int(11),
 
     amt int(11) unsigned not null,
 
     created_on datetime
 
  )partition by range(year(created_on))(
 
  partition p2018 values less than (2018),
 
  partition p2019 values less than (2019),
 
  partition p2020 values less than (2020)
 
  partition pdefault values less than maxvalue  #MAXVALUE 表示最大的可能的整数值
 
  );
 
#或者使用id作为范围分区
 
create table table_range(
 
     id int(11),
 
     amt int(11) unsigned not null,
 
     created_on datetime
 
  )partition by range(id)(
 
  partition p10000 values less than (10000),
 
  partition p20000 values less than (20000),
 
  partition p30000 values less than (30000)
 
  partition pdefault values less than maxvalue  #MAXVALUE 表示最大的可能的整数值
 
  );

范围分区

所有范围区间不能重叠。

查询条件里包括分区键,免全表扫描,分区表查询都应该注意这个。

分区键一般是时间或是唯一的索引值,一般都会在每条数据上计算并保存分区字段。

实例

假如我们现在有一张大表需要做分区:

过程应该如下建新表–>备份–>停机-》删原表–>改名〉恢复

CREATE TABLE `t_send_message_send2` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `plan_id` bigint(20) DEFAULT NULL,
  `job_uuid` varchar(36) DEFAULT NULL,
  `send_port` varchar(16) DEFAULT NULL,
  `mobile` varchar(16) DEFAULT NULL,
  `content` varchar(200) DEFAULT NULL,
  `product_code` varchar(16) DEFAULT 'HELP',
  `fake` bit(1) DEFAULT b'0',
  `date_push` datetime NOT NULL,
  `activity_id` bigint(20) DEFAULT '0',
  PRIMARY KEY (`id`,`date_push`),
  KEY `mobile` (`mobile`),
  KEY `date_push` (`date_push`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE  COLUMNS(date_push)
(PARTITION p2016 VALUES LESS THAN ('2017-01-01') ENGINE = InnoDB,
 PARTITION p2017 VALUES LESS THAN ('2018-01-01') ENGINE = InnoDB,
 PARTITION p2018 VALUES LESS THAN ('2019-01-01') ENGINE = InnoDB,
 PARTITION p2019 VALUES LESS THAN ('2020-01-01') ENGINE = InnoDB,
 PARTITION p2020 VALUES LESS THAN ('2021-01-01') ENGINE = InnoDB);

②备份

备份的方式有两类:

a、在线备份

数据一直在数据库中不离线。(最好的方式是把备库拉出来做,做分区。再做主备切换)

insert into t_send_message_send2 (select * from t_send_message_send);

b、离线备份

数据先导出到本地,再从本地导回数据库。这种需要先停机,时间较长

③删原表

drop table t_send_message_send;

注意:删原表前一定要确认数据备份完成,且完整。

后面再做增量同步,保证数据不丢失。

rename table t_send_message_send to t_send_message_send_bak;

④改名

rename table t_send_message_send2 to t_send_message_send;

附:

1、查询表分区情况

select partition_name part,partition_expression expr,partition_description descr,table_rows from information_schema.partitions where table_schema = schema() and table_name='t_send_message_send';

1

2、查询表分区数据

select * from t_send_message_send partition(p2020);

mysql分区表对用户来说,分区表是一个独立的逻辑表,但是底层由多个物理子表组成。
实现分区的代码实际上是对一组底层表的句柄对象的封装。mysql在创建表时使用PARTITIONBY子句定义每个分区存放的数据。
在执行查询的时候, 优化器 会根据分区定义过滤那些没有我们需要数据的分区,这样查询就无须扫描所有分区——只需要查询包含需要数据的分区就可以了。
分区的一个主要目的是将数据按照一个较粗的粒度分在不同的表中,这样做可以将相关的数据放在一起,另外,如果想一次批量删除整个分区的数据也会变得很方便。

a),mysql 的分表是真正的分表,一张表分成很多表后,

每一个小表都是完正的一张表,都对应三个文件, 一个.MYD 数据文件,.MYI 索引文件,.frm 表结构文件。

在下面的场景中,分区可以起到非常大的作用:

  • 1.表非常大以至于无法全部都放在内存中,或者只在表的最后部分有热点数据,其他均是历史数据。

  • 2.分区表的数据更容易维护。例如想批量删除大量数据可以使用清除整个分区的方式。另外,还可以对一个独立分区进行优化、检查、修复等操作。

  • 3.分区表的数据可以分布在不同的物理设备上,从而高效地利用多个硬件设备。

  • 4.可以使用分区表来避免某些特殊的瓶颈,例如InnoDB的单个索引的互斥访问,ext3文件系统的inode锁竞争等。

  • 5.如果需要,还可以备份和恢复独立的分区,这在非常大的数据集的场景下效果非常好。

分区表本身也有一些限制,下面是其中比较重要的几点:

  • 1.一个表最多只能有1024个分区。

  • 2.在mysql5.1中,分区表达式必须是整数,或者是返回整数的表达式。在mysql5.5中,某些场景中可以直接使用列进行分区。

  • 3.如果分区字段中有主键或者唯一索引的列,那么所有主键列和唯一索引列都必须包含进来。

  • 4.分区表中无法使用外键约束。

分区表上的操作按照下面的操作逻辑进行:

select查询

当查询一个分区表的时候,分区层先打开并锁住所有的底层表,优化器先判断是否可以过滤部分分区,然后再调用对应的存储引擎接口访问各个分区的数据。

insert操作

当写入一条记录时,分区层先打开并锁住所有的底层表,然后确定哪个分区接收这条记录,再将记录写入对应底层表。

delete操作

当删除一条记录时,分区层先打开并锁住所有的底层表,然后确定数据对应的分区,最后对相应底层表进行删除操作。

update操作

当更新一条记录时,分区层先打开并锁住所有的底层表,mysql先确定需要更新的记录在哪个分区,然后取出数据并更新,再判断更新后的数据在哪个分区,最后对底层进行写入操作,并对原数据所在的底层表进行删除操作。

虽然每个操作都有“先打开并锁住所有的底层表”,但这并不是说分区表在处理过程中是锁住全表的。如果存储引擎能够自己实现行级锁,例如innoDb,则会在分区层释放对应表锁。这个加锁和解锁过程与普通InnoDB上的查询类似。


  1. mysql数据库中的数据是以文件的形势存在磁盘上的,默认放在/mysql/data下面(可以通过my.cnf中的datadir来查看),一张表主要对应着三个文件,一个是frm存放表结构的,一个是myd存放表数据的,

  1. 一个是myi存表索引的。如果一张表的数据量太大的话,那么myd,myi就会变的很大,查找数据就会变的很慢,这个时候我们可以利用mysql的分区功能,

  1. 在物理上将这一张表对应的三个文件,分割成许多个小块,这样呢,我们查找一条数据时,就不用全部查找了,只要知道这条数据在哪一块,然后在那一块找就行了。

  1. 如果表的数据太大,可能一个磁盘放不下,这个时候,我们可以把数据分配到不同的磁盘里面去

reate table employees (
id int not null primary key,
first_name varchar(30),
last_name varchar(30))
partition by range(id)(
partition p0 values less than (11),
partition p1 values less than (21),
partition p2 values less than (31),
partition p3 values less than (41)
);
insert into employees values(1,'Vincent','Chen');
insert into employees values(6,'Victor','Chen');
insert into employees values(11,'Grace','Li');
insert into employees values(16,'San','Zhang');

2)explain partitions:相比 explain 多了个 partitions 字段,如果查询是基于分区表的话,会显示查询将访问的分区。

查询到这条数据,是从p1里面找到的。

找不到,所以不是从哪个分区找到的。

查询条件不是分区建立的条件,所以走所有分区。

我们增加分区条件id

阿里不建议分区,而是分表:

因此,如果要使用分区表,就不要创建太多分区。我见过一个用户做了按天分区策略,然后预先创建了10年的分区。这种情况下,访问分区表的性能自然是不好的。这里有两个问题:

  • 分区并不是越细越好 单表或单分区的数据一千万行,只要没有特别大的索引,对于现在的硬件能力来说都已是小表

  • 分区不要提前预留太多,在使用之前预先创建即可 比如,如果是按月分区,每年年底时再把下一年度的12个新分区创建上即可。对于没有数据的历史分区,及时drop

分区表的其他问题,比如查询需要跨多个分区取数据,查询性能就会比较慢,基本上就不是分区表本身的问题,而是数据量或说使用方式问题。 如果你的团队已经维护了成熟的分库分表中间件,用业务分表,对业务开发同学没有额外的复杂性,对DBA也更直观,自然更好。

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

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

相关文章

第四讲:如何将本地代码与服务器代码保持实时同步

一、前言 在我们进行 Ambari 二次开发时,通常会先在服务器上部署一套可以使用的 Ambari 环境。 二次开发,就肯定是要改动代码的,我们不能老是在服务器上用vim编辑文件,那样效率太低,始终不是长久之计。 所以我们需要在本地打开我们的Ambari源码项目,比如用idea工具,可…

【电子学会】2022年12月图形化二级 -- 绘制风车

绘制风车 1. 准备工作 (1)隐藏默认的小猫角色; (2)选择背景:“Xy-grid”。 2. 功能实现 (1)小猫角色的初始位置为(x:0,y:0); (2)线条粗细为…

实验4 设计模式实验3

实验内容: 1. 某软件公司为新开发的智能手机控制与管理软件提供了一键备份功能,通 过该功能可以将原本存储在手机中的通信录、短信、照片、歌曲等资料一次性全 部拷贝到移动存储介质(例如MMC 卡或SD 卡)中。在实现过程中需要与多个 已有的类进行交互,例如通讯录管理类、短信…

黑马Spring学习笔记(四)——面向切面编程AOP

目录 一、AOP简介 二、AOP核心概念 三、AOP入门案例 四、AOP配置管理 4.1 AOP切入点表达式 4.1.1 语法格式 4.2.2 通配符 4.2.3 书写技巧 4.2 AOP通知类型 4.2.1 前置、后置、返回后、抛出异常后获取参数 4.2.2 环绕通知 一、AOP简介 AOP(Aspect Oriented Pro…

【IoT】创业成功不可或缺的两个因素:能力和趋势

今天就来谈谈能力和趋势究竟哪个更重要的问题。 在谈成功的十大要素时,我曾经讲到: 一命、二运、三风水,这三个要素几乎不涉及任何个人的努力。 而趋势跟这三个要素又是息息相关的,这也类似雷军所说的飞猪理论。 只要风足够大&…

Centos7(阿里云)_安装Mysql8.0

1.安装MySQL 新人可以试用一个月的阿里云,centos7的 一开始可能确实会自带mariadb,所以可以在网上随便找个教程开始尝试安装MySQL,当然大概率出错,然后此时你的rpm下面已经有了一个版本的mysql安装包。 以我为例,随便…

Windows下jdk安装与卸载-超详细的图文教程

jdk安装 下载jdk 由于现在主流就是jdk1.8,所以这里就下载jdk1.8进行演示。官方下载地址:https://www.oracle.com/java/technologies/downloads/#java8-windows。 官方下载需要注册oracle账号,国内下载有可能速度慢,若不想注册账…

【Linux】P5 实用快捷键 以及 下载安装指令

Linux实用快捷键与下载安装实用快捷键强制停止退出账户 / 环境查看历史命令光标移动快捷键清屏下载安装命令CentOS - yumUbunto - apt实用快捷键 强制停止 CTRL C当程序陷入死循环或者执行错误,可通过该命令强制停止 当程序输入很长但是发现错误,不想…

PDF 解析格式化输出 API 数据接口

PDF 解析格式化输出 API 数据接口 支持输出 TEXT HTML XML TAG,多种格式输出,超精准识别率。 1. 产品功能 通用的识别接口, 支持标准 PDF 文件解析;多种格式输出,支持 TEXT HTML XML TAG;HTML 包含完美排…

蒙特卡洛树搜索(MTCS)

一、目标 一种启发式的搜索算法,在搜索空间巨大的场景下比较有效 算法完成后得到一棵树,这棵树可以实现:给定一个游戏状态,直接选择最佳的下一步 二、算法四阶段 1、选择(Selection) 父节点选择UCB值最…

【ONE·C || 文件操作】

总言 C语言:文件操作。    文章目录总言1、文件是什么?为什么需要文件?1.1、为什么需要文件?1.2、文件是什么?2、文件的打开与关闭2.1、文件指针2.2、文件打开和关闭:fopen、fclose2.3、文件使用方式3、文…

windows下go安装并使用protobuf

go使用protobuf的过程以及可能出现的问题1. 下载proto windows版本并安装2. 安装protoc-gen-go3. proto文件转go文件报错protoc-gen-go: unable to determine go import path for "xxxx.proto"4. 生成的go文件中google.golang.org/protobuf/reflect/protoreflect依赖…

Zookeeper3.5.7版本——客户端命令行操作(znode 节点数据信息)

目录一、命令行语法二、znode 节点数据信息2.1、查看当前znode中所包含的内容2.2、查看当前节点详细数据2.3、节点详细数据解释一、命令行语法 命令行语法列表 命令基本语法功能描述help显示所有操作命令ls path使用 ls 命令来查看当前 znode 的子节点 [可监听]-w 监听子节点变…

粒子群优化最小二乘支持向量机SVM回归分析,pso-lssvm回归预测

目录 支持向量机SVM的详细原理 SVM的定义 SVM理论 SVM应用实例,粒子群优化最小二乘支持向量机SVM回归分析 代码 结果分析 展望 支持向量机SVM的详细原理 SVM的定义 支持向量机(support vector machines, SVM)是一种二分类模型,它的基本模型是定义在特征空间上的间隔最大…

视觉SLAM十四讲ch6 非线性优化笔记

视觉SLAM十四讲ch6 非线性优化笔记本讲目标上讲回顾状态估计问题非线性最小二乘Gauss-Newton:高斯牛顿Levenburg-Marquadt:列文伯格-马夸尔特小结实践:CERES实践:G2O本讲目标 理解最小二乘法的含义和处理方式。 理解Gauss-Newton…

CopyOnWriteArrayList 源码解读

一、CopyOnWriteArrayList 源码解读 在 JUC 中,对于 ArrayList 的线程安全用法,比较推崇于使用 CopyOnWriteArrayList ,那 CopyOnWriteArrayList是怎么解决线程安全问题的呢,本文带领大家一起解读下 CopyOnWriteArrayList 的源码…

Day908.joinsnljdist和group问题和备库自增主键问题 -MySQL实战

join&snlj&dist和group问题和备库自增主键问题 Hi,我是阿昌,今天学习记录的是关于join&snlj&dist和group问题和备库自增主键问题的内容。 一、join 的写法 join 语句怎么优化?中,在介绍 join 执行顺序的时候&am…

基础复习第二十三天  File类与IO流的使用

java.io.File类:文件或文件目录路径的抽象表现形式,与平台无关。概述File能新建、删除、重命名文件或目录,但File不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。想要在Java程序中表示一个真实存在的文件或目录&…

【Java并发编程】CountDownLatch

CountDownLatch是JUC提供的解决方案 CountDownLatch 可以保证一组子线程全部执行完牛后再进行主线程的执行操作。例如,主线程启动前,可能需要启动并执行若干子线程,这时就可以通过 CountDownLatch 来进行控制。 CountDownLatch是通过一个线程…

6. unity之脚本

1. 说明 当整个游戏运行起来之后,我们无法再借助鼠标来控制物体,此时可以使用脚本来更改物体的各种姿态,驱动游戏的整体运动逻辑。 2. 脚本添加 首先在Assets目录中,新创建一个Scripts文件夹,在该文件内右键鼠标选择…