MySQL 8 教程

MySQL 主页 MySQL 简介 MySQL 功能 MySQL 版本 MySQL 变量 MySQL 下载安装和环境配置 MySQL 管理 MySQL PHP 语法 MySQL Node.js 语法 MySQL Java 语法 MySQL Python 语法 MySQL 连接 MySQL Workbench

MySQL 8 数据库

MySQL 创建数据库 MySQL 删除数据库 MySQL 选择数据库 MySQL 显示数据库 MySQL 复制数据库 MySQL 数据库导出 MySQL 数据库导入 MySQL 数据库信息

MySQL 8 用户

MySQL 创建用户 MySQL 删除用户 MySQL 显示用户 MySQL 更改密码 MySQL 授予权限 MySQL 显示权限 MySQL 撤销权限 MySQL 锁定用户账户 MySQL 解锁用户账户

MySQL 8 表

MySQL 创建表 MySQL 显示表 MySQL 修改表 MySQL 重命名表 MySQL 克隆表 MySQL 截断表 MySQL 临时表 MySQL 修复表 MySQL 描述表 MySQL 添加/删除列 MySQL 显示列 MySQL 重命名列 MySQL 表锁定 MySQL 删除表 MySQL 派生表

MySQL 8 查询

MySQL 查询 MySQL 约束 MySQL INSERT 插入查询 MySQL SELECT 查询 MySQL UPDATE 更新查询 MySQL DELETE删除查询 MySQL REPLACE 替换查询 MySQL 忽略插入 MySQL 重复键更新时插入 MySQL 插入到另一个表语句

MySQL 8 视图

MySQL 创建视图 MySQL 更新视图 MySQL 删除视图 MySQL 重命名视图

MySQL 8 索引

MySQL 索引 MySQL 创建索引 MySQL 删除索引 MySQL 显示索引 MySQL 唯一索引 MySQL 聚集索引 MySQL 非聚集索引

MySQL 运算符和子句

MySQL Where 子句 MySQL Limit 子句 MySQL Distinct 子句 MySQL Order By 子句 MySQL Group By 子句 MySQL Having 子句 MySQL AND 运算符 MySQL OR 或运算符 MySQL LIKE 运算符 MySQL IN 运算符 MySQL ANY 运算符 MySQL Exists 运算符 MySQL NOT 运算符 MySQL NOT EQUAL 运算符 MySQL IS NULL 运算符 MySQL IS NOT NULL 运算符 MySQL Between 运算符 MySQL UNION 运算符 MySQL UNION 与 UNION ALL MySQL MINUS 运算符 MySQL INTERSECT 运算符 MySQL INTERVAL 运算符

MySQL 连接

MySQL 使用连接 MySQL Inner Join 内连接 MySQL LEFT JOIN 左连接 MySQL RIGHT JOIN 右连接 MySQL CROSS JOIN 交叉连接 MySQL 全连接 MySQL 自连接 MySQL Delete Join 删除连接 MySQL UPDATE JOIN 更新连接 MySQL 联合 vs 连接

MySQL 键

MySQL UNIQUE 唯一键 MySQL PRIMARY KEY 主键 MySQL FOREIGN KEY 外键 MySQL 复合键 MySQL 备用键

MySQL 触发器

MySQL 触发器 MySQL 创建触发器 MySQL 显示触发器 MySQL 删除触发器 MySQL 插入前触发器 MySQL 插入后触发器 MySQL 更新前触发器 MySQL 更新后触发器 MySQL 删除前触发器 MySQL 删除后触发器

MySQL 8 数据类型

MySQL 数据类型 MySQL VARCHAR MySQL BOOLEAN MySQL ENUM 枚举 MySQL DECIMAL 十进制 MySQL INT 整数 MySQL FLOAT 浮点数 MySQL BIT 位 MySQL TINYINT 微小整数 MySQL BLOB 二进制大对象 MySQL SET 集合

MySQL 正则表达式

MySQL 正则表达式 MySQL RLIKE 运算符 MySQL NOT LIKE 运算符 MySQL NOT REGEXP 运算符 MySQL regexp_instr() 函数 MySQL regexp_like() 函数 MySQL regexp_replace() 函数 MySQL regexp_substr() 函数

MySQL 全文搜索

MySQL 全文搜索 MySQL 自然语言全文搜索 MySQL 布尔全文搜索 MySQL 查询扩展全文搜索 MySQL ngram 全文解析器

MySQL8 函数和运算符

MySQL 日期和时间函数 MySQL 算术运算符 MySQL 数字函数 MySQL 字符串函数 MySQL 聚合函数

MySQL 8 其他概念

MySQL NULL 值 MySQL 事务 MySQL 序列 MySQL 处理重复项 MySQL SQL 注入 MySQL 子查询 MySQL 注释 MySQL 检查约束 MySQL 存储引擎 MySQL 将表导出为 CSV 文件 MySQL 将 CSV 文件导入数据库 MySQL UUID MySQL 通用表表达式 MySQL 级联删除 MySQL Upsert 操作 MySQL 水平分区 MySQL 垂直分区 MySQL 游标 MySQL 存储函数 MySQL SIGNAL 异常处理 MySQL RESIGNAL 异常处理 MySQL 字符集 MySQL 排序规则 MySQL 通配符 MySQL 别名 MySQL ROLLUP 超级聚合 MySQL 当前日期 MySQL 字面量 MySQL 存储过程 MySQL EXPLAIN 语句 MySQL JSON MySQL 标准差 MySQL 查找重复记录 MySQL 删除重复记录 MySQL 选择随机记录 MySQL 显示进程列表 MySQL 更改列类型 MySQL 重置自动增量 MySQL Coalesce() 函数

MySQL 8 实用资源

MySQL 实用函数 MySQL 语句参考 MySQL 快速指南 MySQL 实用资源 MySQL 讨论


MySQL - 水平分区

MySQL 分区是一种将数据库表划分为较小表(即分区)的技术。这些较小的表存储在不同的物理位置,并被视为单独的表。因此,这些小表中的数据可以单独访问和管理。

但请注意,即使小表中的数据单独管理,它们也不是独立的表;也就是说,它们仍然是主表的一部分。

MySQL 中有两种分区形式:水平分区和垂直分区。

MySQL 水平分区

MySQL 水平分区用于将表行划分为多个分区。由于它划分了行,因此所有列都将存在于每个分区中。所有分区都可以单独访问,也可以集中访问。

MySQL 水平分区方法有多种类型 -

MySQL 范围分区

MySQL RANGE 分区用于根据列值的特定范围将表划分为多个分区。每个表分区包含列值在该定义范围内的行。

示例

让我们创建一个名为 CUSTOMERS 的表,并使用"PARTITION BY RANGE"子句根据 AGE 列将其划分为四个分区:P1、P2、P3 和 P4 -

CREATE TABLE CUSTOMERS(
   ID int not null,
   NAME varchar(40) not null,
   AGE int not null,
   ADDRESS char(25) not null,
   SALARY decimal(18, 2)
   )
   PARTITION BY RANGE (AGE) (
   PARTITION P1 VALUES LESS THAN (20),
   PARTITION P2 VALUES LESS THAN (30),
   PARTITION P3 VALUES LESS THAN (40),
   PARTITION P4 VALUES LESS THAN (50)
);

在这里,我们将行插入到上面创建的表中 -

INSERT INTO CUSTOMERS VALUES 
(1, 'Ramesh', 19, 'Ahmedabad', 2000.00 ),
(2, 'Khilan', 25, 'Delhi', 1500.00 ),
(3, 'kaushik', 23, 'Kota', 2000.00 ),
(4, 'Chaitali', 31, 'Mumbai', 6500.00 ),
(5, 'Hardik', 35, 'Bhopal', 8500.00 ),
(6, 'Komal', 47, 'MP', 4500.00 ),
(7, 'Muffy', 43, 'Indore', 10000.00 );

以下是获得的CUSTOMERS表 -

ID NAME AGE ADDRESS SALARY
1 Ramesh 19 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Kaushik 23 Kota 2000.00
4 Chaitali 31 Mumbai 6500.00
5 Hardik 35 Bhopal 8500.00
6 Komal 47 MP 4500.00
7 Muffy 43 Indore 10000.00

现在 CUSTOMERS 表中已经有了一些数据,我们可以使用以下查询显示分区状态,以了解数据在各个分区之间的分布情况 -

SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME='CUSTOMERS';

上述查询将显示每个分区中的行数。例如,P1 有 1 行,P2 有 2 行,P3 有 2 行,P4 有 2 行,如下所示 -

PARTITION_NAME TABLE_ROWS
P1 1
P2 2
P3 2
P4 2

显示分区 -

我们还可以使用 PARTITION 子句显示特定分区的数据。例如,要从分区 P1 检索数据,我们使用以下查询 -

SELECT * FROM CUSTOMERS PARTITION (p1);

它将显示分区 P1 中的所有记录 -

ID NAME AGE ADDRESS SALARY
1 Ramesh 19 Ahmedabad 2000.00

类似地,我们可以使用相同的语法显示其他分区。

处理超出范围的数据 -

如果我们尝试将一个不属于任何已定义分区的值插入到 AGE 列中,则会失败并出现错误,如下所示 -

INSERT INTO CUSTOMERS VALUES
(8, 'Brahmi', 70, 'Hyderabad', 19000.00 );

以下是获取到的错误 -

ERROR 1526 (HY000): Table has no partition for value 70

截断分区 -

我们还可以根据需要通过截断分区来管理分区。例如,要清空分区 P2,我们可以使用以下查询 -

ALTER TABLE CUSTOMERS TRUNCATE PARTITION p2;

获得的输出如下所示 -

Query OK, 0 rows affected (0.03 sec)

这将删除分区 P2 中的所有数据,使其变为空,如下所示 -

SELECT * FROM CUSTOMERS PARTITION (p2);

以下是生成的输出 -

Empty set (0.00 sec)

我们可以使用以下 SELECT 查询验证 CUSTOMERS 表 -

SELECT * FROM CUSTOMERS;

我们可以在下表中看到属于 p2 分区的行已被删除 -

ID NAME AGE ADDRESS SALARY
1 Ramesh 19 Ahmedabad 2000.00
2 Khilan 25 Delhi 1500.00
3 Kaushik 23 Kota 2000.00
6 Komal 47 MP 4500.00
7 Muffy 43 Indore 10000.00

MySQL 列表分区

MySQL 列表分区用于根据特定列的一组离散值将表划分为多个分区。每个分区包含与定义集合中的特定值匹配的行。

示例

在此示例中,我们将创建一个名为 STUDENTS 的表,并使用"PARTITION BY LIST"子句,根据"DEPARTMENT_ID"列将其划分为四个分区(P1、P2、P3 和 P4)-

CREATE TABLE STUDENTS(
   ID int,
   NAME varchar(50),
   DEPARTMENT varchar(50),
   DEPARTMENT_ID int
   )
   PARTITION BY LIST(DEPARTMENT_ID)(
   PARTITION P1 VALUES IN (3, 5, 6, 7, 9),
   PARTITION P2 VALUES IN (13, 15, 16, 17, 20),
   PARTITION P3 VALUES IN (23, 25, 26, 27, 30),
   PARTITION P4 VALUES IN (33, 35, 36, 37, 40)
);

在这里,我们将行插入到上面创建的表中 -

INSERT INTO STUDENTS VALUES 
(1, 'Ramesh', "cse", 5),
(2, 'Khilan', "mech", 20),
(3, 'kaushik', "ece", 17),
(4, 'Chaitali', "eee", 33),
(5, 'Hardik', "IT", 36),
(6, 'Komal', "Hotel management", 40),
(7, 'Muffy', "Fashion", 23);

以下是获得的STUDENTS表 -

ID NAME DEPARTMENT DEPARTMENT_ID
1 Ramesh cse 5
2 Khilan mech 20
3 Kaushik ece 17
7 Muffy Fashion 23
4 Chaitali eee 33
5 Hardik IT 36
6 Komal Hotel management 40

我们可以使用以下查询显示 STUDENTS 表的分区状态,以了解数据在各个分区之间的分布情况 -

SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME='STUDENTS';

此查询的输出将显示每个分区中的行数。例如,P1 有 1 行,P2 有 2 行,P3 有 1 行,P4 有 3 行 -

PARTITION_NAME TABLE_ROWS
P1 1
P2 2
P3 1
P4 3

MySQL 哈希分区

MySQL 哈希分区用于使用基于特定列的哈希函数将表数据划分为多个分区。数据将均匀分布在各个分区中。

示例

在以下查询中,我们将创建一个名为 EMPLOYEES 的表,该表使用 PARTITION BY HASH 子句,基于"id"列创建四个分区 -

CREATE TABLE EMPLOYEES (
   id INT NOT NULL,
   name VARCHAR(50) NOT NULL,
   department VARCHAR(50) NOT NULL,
   salary INT NOT NULL
 )
   PARTITION BY HASH(id)
   PARTITIONS 4;

在这里,我们将行插入到上面创建的表中 -

INSERT INTO EMPLOYEES VALUES 
(1, 'Varun', 'Sales', 50000),
(2, 'Aarohi', 'Marketing', 60000),
(3, 'Paul', 'IT', 70000),
(4, 'Vaidhya', 'Finance', 80000),
(5, 'Nikhil', 'Sales', 55000),
(6, 'Sarah', 'Marketing', 65000),
(7, 'Tim', 'IT', 75000),
(8, 'Priya', 'Finance', 85000);

获得的EMPLOYEES表如下 −

id name department salary
4 Vaidhya Finance 80000
8 Priya Finance 85000
1 Varun Sales 50000
5 Nikhil Sales 55000
2 Aarohi Marketing 60000
6 Sarah Marketing 65000
3 Paul IT 70000
7 Tim IT 75000

记录根据"id"列均匀分布在四个分区中。您可以使用以下 SELECT 查询验证分区状态 -

SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME='EMPLOYEES';

得到的表如下 -

PARTITION_NAME TABLE_ROWS
P0 2
P1 2
P2 2
P3 2

键分区

MySQL 键分区用于根据主键或唯一键的值将表数据划分为多个分区。

示例

在以下查询中,我们将创建一个名为 PERSON 的表,并根据"id"列进行键分区。我们将该表划分为四个分区,主键为"id" -

CREATE TABLE PERSON (
   id INT NOT NULL,
   name VARCHAR(50) NOT NULL,
   email VARCHAR(50) NOT NULL,
   address VARCHAR(100) NOT NULL,
   PRIMARY KEY (id)
   )
   PARTITION BY KEY(id)
   PARTITIONS 4;

在这里,我们将行插入到上面创建的表中 -

INSERT INTO PERSON VALUES 
(1, 'Krishna', 'Krishna@tutorialspoint.com', 'Ayodhya'),
(2, 'Kasyap', 'Kasyap@tutorialspoint.com', 'Ayodhya'),
(3, 'Radha', 'Radha@tutorialspoint.com', 'Ayodhya'),
(4, 'Sarah', 'Sarah@tutorialspoint.com', 'Sri Lanka'),
(5, 'Sita', 'Sita@tutorialspoint.com', 'Sri Lanka'),
(6, 'Arjun', 'Arjun@tutorialspoint.com', 'India'),
(7, 'Hanuman', 'Hanuman@tutorialspoint.com', 'Sri Lanka'),
(8, 'Lakshman', 'Lakshman@tutorialspoint.com', 'Sri Lanka');

以下是获得的PERSON表 -

id name email address
1 Krishna Krishna@tutorialspoint.com Ayodhya
5 Sita Sita@tutorialspoint.com Sri Lanka
4 Sarah Sarah@tutorialspoint.com Sri Lanka
8 Lakshman Lakshman@tutorialspoint.com Sri Lanka
3 Radha Radha@tutorialspoint.com Ayodhya
7 Hanuman Hanuman@tutorialspoint.com Sri Lanka
2 Kasyap Kasyap@tutorialspoint.com Ayodhya
6 Arjun Arjun@tutorialspoint.com India

同样,数据根据"id"列均匀分布在各个分区之间,您可以使用以下查询验证分区状态 -

SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME='PERSON';

获得的输出如下所示 -

PARTITION_NAME TABLE_ROWS
P0 2
P1 2
P2 2
P3 2

MySQL 子分区

MySQL 子分区用于根据其他列进一步划分分区,通常与其他分区方法(如 RANGE 或 HASH)结合使用。

示例

我们创建一个 CUSTOMER_ORDERS 表,在"order_date"列上进行 RANGE 分区,然后根据"order_date"的月份进行哈希子分区 -

CREATE TABLE CUSTOMER_ORDERS (
   order_id INT NOT NULL,
   customer_name VARCHAR(50) NOT NULL,
   order_date DATE NOT NULL,
   order_status VARCHAR(20) NOT NULL
   )
   PARTITION BY RANGE (YEAR(order_date))
   SUBPARTITION BY HASH(MONTH(order_date))
   SUBPARTITIONS 2(
   PARTITION p0 VALUES LESS THAN (2022),
   PARTITION p1 VALUES LESS THAN (2023),
   PARTITION p2 VALUES LESS THAN (2024)
);

在这里,我们将行插入到上面创建的表中 -

INSERT INTO CUSTOMER_ORDERS VALUES 
(1, 'John', '2021-03-15', 'Shipped'),
(2, 'Bob', '2019-01-10', 'Delivered'),
(3, 'Johnson', '2023-01-10', 'Delivered'),
(4, 'Jake', '2020-01-10', 'Delivered'),
(5, 'Smith', '2022-05-01', 'Pending'),
(6, 'Rob', '2023-01-10', 'Delivered');

以下是获得的CUSTOMERS_ORDERS表 -

order_id customer_name order_date order_status
1 John 2021-03-15 Shipped
2 Bob 2019-01-10 Delivered
4 Jake 2020-01-10 Delivered
5 Smith 2022-05-01 Pending
3 Johnson 2023-01-10 Delivered
6 Rob 2023-01-10 Delivered

您可以使用以下查询显示 CUSTOMER_ORDERS 表并验证分区状态 -

SELECT PARTITION_NAME, TABLE_ROWS
FROM INFORMATION_SCHEMA.PARTITIONS
WHERE TABLE_NAME='CUSTOMER_ORDERS';

以下是获取的表 -

PARTITION_NAME TABLE_ROWS
P0 0
P0 3
P1 0
P1 1
P2 0
P2 2