炸锅了,MySQL表500W行,居然有人不做分区?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 炸锅了,MySQL表500W行,居然有人不做分区?

下面由邦德老师,给大家详细的介绍下MySQL的分区吧~


🚀 1.分区表



🌈 1.1 什么是表分区


我们可以通过 show variables like ‘%datadir%’;

命令来查看数据文件存放的默认路径,一个数据库就是一个文件夹,一个库中。

只要一张表的数据量过大,就会导致 *.ibd 文件过大,数据的查找就会变的很慢。

一般生产上建议单天超过10万行,建议分区,1亿条数据大约1G


MySQL 从 5.1 开始添加了对分区的支持,

分区的过程是将一个表或索引分解为多个更小、更可管理的部分。

对于开发者而言,分区后的表使用方式和不分区基本上还是一模一样,只不过在物理存储上,

原本该表只有一个数据文件,现在变成了多个,每个分区都是独立的对象,可以独自处理,也可以作为一个更大对象的一部分进行处理。


fe17e8ca0adc46299fb1b2be2009aa47.png


常见的存储引擎如 InnoDB、MyISAM、NDB 等都支持分区。

但并不是所有的存储引擎都支持,如 CSV、FEDORATED、MERGE 等就不支持分区,

因此在使用此分区功能前,应该对选择的存储引擎对分区的支持有所了解。


7699f3a28c7c4d7b8c0beac3945f82b3.png


🌈 1.2 为什么需要表分区


1.可以让单表存储更多的数据。

2.分区表的数据更容易维护,可以通过清除整个分区批量删除大量数据,

也可以增加新的分区来支持新插入的数据。另外,还可以对一个独立分区进行优化、检查、修复等操作。

3.部分查询能够从查询条件确定只落在少数分区上,查询速度会很快。

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

5.可以使用分区表来避免某些特殊瓶颈,

例如 InnoDB单个索引的互斥访问、ext3文件系统的inode锁竞争。

可以备份和恢复单个分区。


🌈 1.3 分区表的缺点


🚩表分区的主要缺点


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

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

3.分区表无法使用外键约束。

4.NULL 值会使分区过滤无效。

5.所有分区必须使用相同的存储引擎。


🚩表分区的主要优点


1、可以允许在一个表里存储更多的数据,突破磁盘限制和文件系统限制。

2、对于从表里删除过期的历史数据比较容易,只需要移除对应的分区。

3、对于某些查询或修改语句,可以自动将数据范围缩小到一个至几个分区上,优化语句执行效率。


🚀 2.分区表的类型



🌈 2.1 RANGE分区


范围表分区,按照一定的范围值来确定每个分区包含的数据,如上使用的就是range表分区;

语法:partition by range(id) partition p0 values less than()

分区的定义范围必须是连续的,且不能重叠,使用values less than()来定义分区范围,从小到大定义范围。

给分区字段赋值的时候分区字段取值范围不能超过values less than()的取值范围。

使用values less than maxvalue来将未来不确定的值放到这个表分区中。

按时间类型(datetime)来做表分区可以在RANGE()中使用函数来做转换,

例如:partition by range(year(create_time)),timestamp可以使用unix_timestamp(‘2019-11-20 00:00:00’)转化


create table user_range(
  id int,
  username varchar(255),
  password varchar(255),
  createDate date,
  primary key (id,createDate)
) engine=innodb
  partition by range(year(createDate))(
     partition  p2022  values  less  than(2023),
     partition  p2023  values  less  than(2024),
     partition  p2024  values  less  than(2025)  
);


🚩 注意:

createDate 是联合主键的一员。**如果 createDate 不是主键,

只是一个普通字段,那么创建时就会抛出如下错误:

b6f362c37ac14c9bbc27c6e964767fed.png

🚩 删除分区

alter table user_range drop partition p2022;

🚩 新增分区

alter table user_range add partition(partition p2025 values less than(2026));


🌈 2.2 LIST分区


语法: partition by list(id) partition p0 values in(1,2,3)

分区字段必须是整数类型或者分区函数返回整数,取值范围通过values in()来定义,不能使用maxvalue。

假设我有一个用户表,用户有性别,现在想按照性别将用户分开存储,

男性存储在一个分区中,女性存储在一个分区中,SQL 如下:


create  table user_list(
  id int,
  username varchar(255),
  password varchar(255),
  gender int,
  primary key(id, gender)
)engine=innodb
  partition by list(gender)(
     partition  man  values  in  (1),
     partition  woman  values  in  (0)
  );


🌈 2.3 HASH分区


哈希表分区,按照一个自定义的函数返回值来确定每个分区包含的数据

HASH 分区的目的是将数据均匀地分布到预先定义的各个分区中,

保证各分区的数据量大致都是一样的。在 RANGE 和 LIST 分区中,

必须明确指定一个给定的列值或列值集合应该保存在哪个分区中;

而在 HASH 分区中,MySQL 自动完成这些工作,

用户所要做的只是基于将要进行哈希分区的列指定一个表达式,并且分区的数量。

使用 HASH 分区来分割一个表,要在 CREATE TABLE 语句上添加 PARTITION BY HASH (expr),

其中 expr 是一个字段或者是一个返回整数的表达式;另外通过 PARTITIONS 属性指定分区的数量,

如果没有指定,那么分区的数量默认为 1,另外,HASH 分区不能删除分区,

所以不能使用 DROP PARTITION 操作进行分区删除操作。

语法:partition by hash(id) partitions 4

根据hash算法来分配到分区中,以上设置四个分区,并根据id%4进行取模运算,根据余数插入到指定的分区中。


🚩 create table user7(id int) partition by hash(id) partitions 3;


🌈 2.4 KEY分区


KEY 分区和 HASH 分区相似,但是 KEY 分区支持除 text 和 BLOB 之外的所有数据类型的分区,

而 HASH 分区只支持数字分区。KEY 分区不允许使用用户自定义的表达式进行分区,

KEY 分区使用系统提供的 HASH 函数进行分区。当表中存在主键或者唯一索引时,

如果创建 KEY 分区时没有指定字段系统默认会首选主键列作为分区字段,

如果不存在主键列会选择非空唯一索引列作为分区字段。

key()括号里面可以包含0个或多个字段(不必是整数类型,可以是普通字段)

create table user_key(
  id int,
  username varchar(255),
  password varchar(255),
  gender int,
  primary key(id, gender)
)engine=innodb partition by key() partitions 4;

34aa336e02274fda9c91edf5cd345ae3.png


🌈 2.5 多字段分区


可以指定多个字段作为分区字段

COLUMN 分区是 5.5 开始引入的分区功能,只有 RANGE COLUMN 和 LIST COLUMN 这两种分区;

支持整形、日期、字符串;这种分区方式和 RANGE、LIST 的分区方式非常的相似。

COLUMNS Vs RANGE Vs LIST 分区:

针对日期字段的分区不需要再使用函数进行转换了。

COLUMN 分区支持多个字段作为分区键但是不支持表达式作为分区键。

COLUMNS 支持的类型

整形支持:tinyint、smallint、mediumint、int、bigint;不支持 decimal 和 float。

时间类型支持:date、datetime。

字符类型支持:char、varchar、binary、varbinary;不支持text、blob。


create table user1(
  id int,
  username varchar(255),
  password varchar(255),
  gender int,
  createDate date,
  primary key(id, createDate)
)engine=innodb PARTITION BY RANGE COLUMNS(createDate) (
    PARTITION p0 VALUES LESS THAN ('1990-01-01'),
    PARTITION p1 VALUES LESS THAN ('2000-01-01'),
    PARTITION p2 VALUES LESS THAN ('2010-01-01'),
    PARTITION p3 VALUES LESS THAN ('2020-01-01'),
    PARTITION p4 VALUES LESS THAN MAXVALUE
);
create table user2(
  id int,
  username varchar(255),
  password varchar(255),
  gender int,
  createDate date,
  primary key(id, createDate)
)engine=innodb PARTITION BY LIST COLUMNS(createDate) (
    PARTITION p0 VALUES IN ('1990-01-01'),
    PARTITION p1 VALUES IN ('2000-01-01'),
    PARTITION p2 VALUES IN ('2010-01-01'),
    PARTITION p3 VALUES IN ('2020-01-01')
);


🚀 3.常见分区管理命令



1.添加分区:

alter table user add partition (partition p3 values less than (4000)); – range 分区

alter table user add partition (partition p3 values in (40)); – lists分区

2.删除表分区(会删除数据):

alter table user drop partition p30;

3.删除表的所有分区(不会丢失数据):

alter table user_list remove partitioning;

4.重新定义 list分区表(不会丢失数据):

alter table user_list partition by list(gender)(

partition man values in (1),

partition woman values in (0)

);

5.重新定义 hash 分区表(不会丢失数据):

alter table user partition by hash(salary) partitions 7;

6.合并分区:把 2 个分区合并为一个,不会丢失数据:

alter table user reorganize partition p1,p2 into (partition p1 values less than (30));

注意:合并之后范围取最大

6.数据字典查询

select * from information_schema.partitions

where table_schema=‘jeames’ and table_name=‘user’\G


🚀 4.表分区实战



🌈 4.1 分区管理


–创建分区表

create table user(id int(11) not null,name varchar(32) not null)

partition by range(id)

(

partition p0 values less than(10),

partition p1 values less than(20),

partition p2 values less than(30),

partition p3 values less than maxvalue

)


🚩 数据存储文件将根据分区被拆分成多份


dd34ff8d083b4bd1b2e74b2f47763329.png


insert into user values(1,‘IT’);

insert into user values(12,‘007’);

insert into user values(22,‘jeames’);

insert into user values(50,‘TenKE’);

select * from user partition(p0);

select * from user partition(p1);

select * from user partition(p2);

select * from user partition(p3);

新增几条数据后查询可以看到数据已经分散在不同的分区中

754145a892ad4fd1baebaf05467499e0.png


🌈 4.2 普通表与分区表的互转


🚩 普通表转分区表语句:

ALTER TABLE students PARTITION BY KEY(sid) PARTITIONS 2;


0f86241dc28f41089e6bb50f36f1972f.png

🚩移除分区信息

ALTER TABLE fg_pm_nbiot_cel_h_cel remove partitioning;


f7046468c5834d5294d0e78d46821a86.png


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
27天前
|
SQL 监控 关系型数据库
MySQL如何查看每个分区的数据量
通过本文的介绍,您可以使用MySQL的 `INFORMATION_SCHEMA`查询每个分区的数据量。了解分区数据量对数据库优化和管理具有重要意义,可以帮助您优化查询性能、平衡数据负载和监控数据库健康状况。希望本文对您在MySQL分区管理和性能优化方面有所帮助。
76 1
|
6月前
|
关系型数据库 MySQL 数据库
数据迁移脚本优化过程:从 MySQL 到 Django 模型表
在大规模的数据迁移过程中,性能问题往往是开发者面临的主要挑战之一。本文将分析一个数据迁移脚本的优化过程,展示如何从 MySQL 数据库迁移数据到 Django 模型表,并探讨优化前后的性能差异。
|
2月前
|
存储 关系型数据库 MySQL
MySQL 如何查看每个分区的数据量
MySQL 如何查看每个分区的数据量
37 3
|
5月前
|
DataWorks 安全 关系型数据库
DataWorks产品使用合集之如何实现MySQL数据库的自动分区
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
5月前
|
存储 SQL 关系型数据库
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
MySQL设计规约问题之在数据库设计中,为什么要适当考虑反范式的表设计
|
5月前
|
SQL 存储 数据库
MySQL设计规约问题之如何处理日志类型的表
MySQL设计规约问题之如何处理日志类型的表
|
6月前
|
关系型数据库 MySQL
蓝易云 - 如何修复MySQL中损坏的表
最后,为了防止数据丢失,定期备份数据是非常重要的。
154 3
|
5月前
|
运维 关系型数据库 MySQL
实时计算 Flink版产品使用问题之在处理MySQL表新增数据记录时,没有正确触发变更事件,该如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
5月前
|
负载均衡 关系型数据库 MySQL
MySQL PXC集群多个节点同时大量并发update同一行
如本文标题,MySQL PXC集群多个节点同时大量并发update同一行数据,会怎样? 为此,本人做了一个测试,来验证到底会怎样!
54 0
|
6月前
|
SQL 关系型数据库 MySQL
ClickHouse(23)ClickHouse集成Mysql表引擎详细解析
ClickHouse的MySQL引擎允许执行`SELECT`查询从远程MySQL服务器。使用`MySQL('host:port', 'database', 'table', 'user', 'password'[,...])`格式连接,支持简单`WHERE`子句在MySQL端处理,复杂条件和`LIMIT`在ClickHouse端执行。不支持`NULL`值,用默认值替换。系列文章涵盖ClickHouse安装、集群搭建、表引擎解析等主题。[链接](https://zhangfeidezhu.com/?p=468)有更多
268 0