讲师中心 微信公众号
AI工具推荐 视频效率加速

MySQL搞清什么是分区表?什么是临时表?

秋墨同学_1192

秋墨同学_1192

发布时间:2021-09-14 18:43:08

|

1957人浏览过

|

来源于掘金社区

转载

什么是分区表?什么是临时表?下面本篇文章带大家了解一下mysql中的分区表和临时表,希望对大家有所帮助!

MySQL搞清什么是分区表?什么是临时表?

临时表

MySQL中有一种表叫做临时表,指的是用CREATE TEMPORARY TABLE语句创建的,它是一种特殊类型的表,它允许存储临时结果,可以在单个会话中多次重复使用,对其他连接是不可见的,当连接中断后,数据表就会丢失,但也可以使用DROP TABLE在不需要它的情况下显式删除。【相关推荐:mysql视频教程】

CREATE TEMPORARY TABLE table_name( 
column_1_definition, 
column_2_definition,
....
);

如果想要创建一个与现有表结构相同的临时表,使用CREATE TEMPORARY TABLE语句那就太麻烦了,可以使用下面语句

CREATE TEMPORARY TABLE temp_table_name SELECT * FROM table_name LIMIT 0;

还有一个特点是,临时表可以与其他表具有相同的名称,例如即使数据库中存在user的表,但也可以在数据库中创建user的临时表。

创建临时表示例

创建一个名为tblemployee的新临时表,此时使用SHOW TABLES是无法看到这张表的。

create temporary table tblemployee
(
id int auto_increment Primary key,
emp_name varchar(500),
emp_address varchar(500),
emp_dept_id int
)

向其插入数据。

mysql> insert into tblemployee values(1,'张三','北京',2);
Query OK, 1 row affected (0.00 sec)

mysql> select * from tblemployee;
+----+----------+-------------+-------------+
| id | emp_name | emp_address | emp_dept_id |
+----+----------+-------------+-------------+
|  1 | 张三     | 北京        |           2 |
+----+----------+-------------+-------------+
1 row in set (0.01 sec)

mysql>

基于现有表结构创建

首先创建两个表。

create table tb_user(user_name varchar(255),user_id int(11));

insert tb_user values("张三",1);
insert tb_user values("李四",2);
insert tb_user values("王五",3);

create table balance(user_id int(11),balance decimal(5,2));
insert balance values(1,200);
insert balance values(2,150);
insert balance values(3,100);

创建一个具有姓名和余额的临时表

create temporary table temp_user_balance select user_name,balance from tb_user left join balance on tb_user.user_id=balance.user_id;

查看临时表中数据。

mysql> select * from temp_user_balance;
+-----------+---------+
| user_name | balance |
+-----------+---------+
| 张三      |  200.00 |
| 李四      |  150.00 |
| 王五      |  100.00 |
+-----------+---------+
3 rows in set (0.00 sec)

但是当其他会话查看这个表时,会报错。

mysql> select * from temp_user_balance;
ERROR 1146 (42S02): Table 'test.temp_user_balance' doesn't exist
mysql>

删除临时表

DROP TEMPORARY TABLE table_name;

分区表

MySQL在5.1的时候开始支持分区功能,分区指的是根据一定规则,把同一张表中不同行的记录分配到不同的物理文件中,每个区都是独立的,可以独立处理,也可以作为表的一部分处理,分区对应用来说是透明的,不会影响业务。

MySQL只支持水平分区,不支持垂直分区,水平分区是将同一张表不同行的记录分配到不同的物理文件中,而垂直分区指将同一张表的不同列记录分配到不同的物理文件中。

可以通过SHOW PLUGINS命令来查看MySQL是否启用了分区功能。

MySQL在创建分区的时候使用partition by语句定义每个分区存放的数据,在查询的时候,优化器会根据分区定义过滤那些没有我们需要数据的分区,这样查询的时候就不用扫描所有分区,提高效率。

分区类型

RANGE分区

他是一种基于一个连续区间范围,把数据分配到不同的分区,是最常用的一种分区类型,下面创建一个以id列区间的分区表。

create table user(id int(11),user_name varchar(255))
partition by range(id)(
partition user0 values less than (100),
partition user1 values less than (200));

创建这个表后,表不再由一个ibd组成,而是由建立时候各个分区的ibd组成,可以先通过下面语句查看data目录位置,然后查看被分区后创建的ibd。

show global variables like "%datadir%"
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)
root@hxl-PC:/var/lib/mysql/test# ls
user#p#user0.ibd  user#p#user1.ibd
root@hxl-PC:/var/lib/mysql/test#

然后我们向里面插入3条数据,但是可以看到第三条id为250的却报错了,原因是要插入一个在分区没有定义的值,MySQL则抛出异常。

mysql> insert user values(50,"张三");
Query OK, 1 row affected (0.01 sec)

mysql> insert user values(150,"张三");
Query OK, 1 row affected (0.01 sec)

mysql> insert user values(250,"张三");
ERROR 1526 (HY000): Table has no partition for value 250
mysql>

解决办法是添加一个MAXXXVALUE值的分区,让大于200的值全存放在这里面,这下就可以插入大于200的值了。

alter table user add partition (partition user3 values less than maxvalue);

mysql> insert user values(250,"张三");
Query OK, 1 row affected (0.02 sec)

可以通过下面语句查询PARTITIONS表下得到每个分区具体信息。

select * from information_schema.partitions where table_schema=database() and table_name='user'\G;

由于现在三个分区,所以会出现三个row,每个row中的TABLE_ROWS表示存放的数量,故现在都是1,还有PARTITION_METHOD表示分区类型。

.....
*************************** 1. row ***************************

             PARTITION_METHOD: RANGE
          SUBPARTITION_METHOD: NULL
         PARTITION_EXPRESSION: `id`
      SUBPARTITION_EXPRESSION: NULL
        PARTITION_DESCRIPTION: 100
                   TABLE_ROWS: 1
.....

也可以使用explain 查看查询时候使用了哪个分区。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载

LIST分区

LIST分区类似于RANGE,只是分区列的值只能存放特定的,就是一个枚举列表的值的集合。而RANGE是连续区间值的集合

create table user (id int(11)) 
partition by list(id)(
partition user0 values in(1,3,5,7,9),
partition user1 values in(0,2,4,6,8)
);

同样插入一些数据,可以看到插入10的时候抛出异常,原因也是插入的数据不再分区定义中。

mysql> insert user values(1);
Query OK, 1 row affected (0.02 sec)

mysql> insert user values(2);
Query OK, 1 row affected (0.01 sec)

mysql> insert user values(6);
Query OK, 1 row affected (0.02 sec)

mysql> insert user values(9);
Query OK, 1 row affected (0.01 sec)

mysql> insert user values(10);
ERROR 1526 (HY000): Table has no partition for value 10
mysql>

而其余1、2、6、9在user0、user1两个分区中各两条。

HASH分区

HASH的目的是将数据均匀的分布到定义的各个分区中,保证各个分区的数据量大致都是一样的, HASH分区没有向RANGE和LIST一样必须规定某个值在哪个分区中保存,HASH分区是自动完成的,我们只需要指定分区数量即可。

create table user (id int(11)) partition by hash(id) partitions 4;

那如何得知这个数据在哪个分区中存储呢,拿500来说,就是通过mod(500,分区数量)来得到,所以500在第1个分区中。

mysql> select mod(500,4)
    -> ;
+------------+
| mod(500,4) |
+------------+
|          0 |
+------------+

在比如31,那么mod(31,4)就是3,所以在第4个分区中,如果把这两个数插入进去,通过information_schema.partitions查看,那么1、4分区的TABLE_ROWS都为1。

通过条件查找数据时,使用到的分区也不一样,比如查找相等的数,那么首先计算这个值应该在哪个分区,然后在进行查找,如果使用<、>来范围查找,则会使用所有分区。

还有HASH可以使用一些函数或其他有效表达式,比如创建时可以使用partition by hash(abs(id)),但并不是所有函数都可以使用,可使用的函数可以参考官网 ;

KEY分区

Key分区和HASH类似,不同的是, HASH 分区允许使用用户自定义的表达式,KEY 分区不允许使用用户自定义的表达式,需要使用 HASH 函数

KEY分区允许多列,而HASH分区只允许一列,另外在有主键或者唯一键的情况下,key中分区列可不指定,默认为主键或者唯一键,如果没有,则必须显性指定列。

create table user(id int(11)) partition by key(id) partitions 4;

但是我并没有找到关于详细分区介绍的算法,而是看到一些说通过PASSWORD的运算,没有搞懂。

Columns分区

Columns分区是5.5引入的分区类型,在此之前,RANGE分区和LIST分区只能支持整数分区,从而需要额外的函数来计算,Columns分区解决了这个问题。

Columns分区可以细分为RANGE Columns 和LIST Columns分区,支持的类型如下:

  • TINYINT、 SMALLINT、 MEDIUMINT、 INT ( INTEGER) 和 BIGINT,但是不支持DECIMAL或 FLOAT。

  • DATE和 DATETIME。

  • CHAR, VARCHAR, BINARY,和 VARBINARY,TEXT和 BLOB列不支持。

create table user (
    a int,
    b int
)
partition by range columns(a, b) (
    partition p0 values less than (5, 12),
    partition p1 values less than (maxvalue, maxvalue)
);

现在插入一些数据

insert into user (a,b) values (4,11);
insert into user (a,b) values (6,13);

第一条由于(4,11) < (5,12) 所以在p0分区,而(6,13) < (5,12) ,超出预期,在p1分区。

子分区

子分区也称为复合分区,可以对分区表RANGE和LIST上分区再进分区。

create table user (id int, purchased date)
    partition by range( year(purchased) )
    subpartition by hash( to_days(purchased) )
    subpartitions 2 (
        partition p0 values less than (1990),
        partition p1 values less than (2000),
        partition p2 values less than maxvalue
);

对NULL的处理

MySQL可以在分区键上使用NULL,会把他当做最小分区来处理,也就是会存放到第一个分区,但是在List分区中,NULL值必须定义在列表中,否则不能被插入。

更多编程相关知识,请访问:编程视频!!

热门AI工具

更多
VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
PixTV官网入口地址合集
PixTV官网入口地址合集

本专题汇总了 PixTV AI 一站式视频创作平台的官方入口与使用教程。无需下载软件,浏览器直接访问即可使用。平台将剧本、图像、视频、声音与剪辑整合在“无限画布”中,接入 GPT Image 2.5、Seedance 2.5 等头部模型。本专题整理了从新建画布、角色锚定、分镜拆分到视频生成与导出的完整操作指南,助你快速上手 AI 短剧与漫剧创作。

40

2026.10.10

Kratos框架HTTP与gRPC服务开发教程
Kratos框架HTTP与gRPC服务开发教程

本专题围绕Kratos框架双协议服务开发,涵盖HTTP路由与处理器编写、参数获取、gRPC服务实现与客户端调用、metadata上下文传递、encoding编解码注册、统一响应封装、超时控制与流式响应实现方法。

20

2026.10.10

Kratos框架Protobuf接口定义与代码生成合集
Kratos框架Protobuf接口定义与代码生成合集

本专题讲解Kratos框架接口定义体系,涵盖proto编写规范、proto add/client/server生成命令、http注解路由、validate校验、OpenAPI文档生成、跨服务proto复用与兼容性设计。

0

2026.10.10

C++虚函数怎么定义和调用
C++虚函数怎么定义和调用

C++虚函数是实现运行时多态的重要机制。本专题从virtual关键字的基本用法入手,介绍基类与派生类之间的函数重写、基类指针调用派生类方法,以及动态绑定的执行过程,帮助初学者掌握虚函数的核心语法。

20

2026.10.10

C++类与对象的封装方法教程
C++类与对象的封装方法教程

C++封装是面向对象编程的核心特性之一,通过类将数据与操作数据的函数组织在一起,并利用访问权限控制外部访问。本专题介绍类的定义、成员变量、成员函数以及public、private和protected的使用方法,帮助初学者掌握封装的基本原理。

20

2026.10.10

C++构造函数定义与调用方法
C++构造函数定义与调用方法

C++构造函数用于初始化类对象,是面向对象编程的重要基础。本专题从构造函数的定义、声明和调用入手,介绍默认构造函数、带参数构造函数、拷贝构造函数及成员初始化列表,帮助初学者掌握对象创建与初始化的基本方法。

20

2026.10.10

Kratos框架零基础入门教程
Kratos框架零基础入门教程

本专题整理Kratos框架入门内容,涵盖Go环境准备、kratos CLI安装升级、new命令创建项目、目录结构分层说明、服务启动与双协议端口、依赖下载报错排查,帮助开发者快速跑通第一个Kratos框架微服务应用。

20

2026.10.10

C++条件判断语句怎么写
C++条件判断语句怎么写

C++条件判断是控制程序执行流程的重要基础。本专题介绍if、if-else、else if和switch等常见分支语句,结合条件表达式、比较运算符与代码示例,帮助初学者掌握不同场景下的判断逻辑。

0

2026.10.10

C++变量怎么声明和赋值
C++变量怎么声明和赋值

C++变量是编写程序和存储数据的基础。本专题围绕变量声明、定义、初始化、赋值和类型选择等内容展开,帮助初学者理解不同变量的用法,并掌握在实际代码中定义和使用变量的方法。

20

2026.10.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 183人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn