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

MySQL分区表(二)

说明:之前有写过一篇博客,介绍MySQL如何建立分区表,本文介绍如何建立子分区表。子分区,就是在原来分区的基础上,再嵌套一个分区。

例如,按照记录的创建时间分区,在此基础上,再按照租户ID嵌套一个子分区。如果按照时间建立了12个分区,租户ID有3个,那么最终建立的子分区就是:12 × 3 = 36个;

下面介绍如何建立和使用子分区:

建立

如下,建立一个子分区表,tb_user;

-- 建立子分区表tb_user
CREATE TABLE `tb_user`
(
    `id`          int         NOT NULL AUTO_INCREMENT,
    `tenant_id`   varchar(50) NOT NULL,
    `username`    varchar(20) DEFAULT NULL,
    `password`    varchar(20) DEFAULT NULL,
    `create_date` bigint      NOT NULL,
    PRIMARY KEY (`id`, `tenant_id`, `create_date`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci
    COMMENT ='用户表'
    PARTITION BY RANGE (`create_date`) SUBPARTITION BY key (`tenant_id`)
        (
        PARTITION tb_user_1735660800000 VALUES LESS THAN (1735660800000)
            (
            SUBPARTITION tb_user_1735660800000_01,
            SUBPARTITION tb_user_1735660800000_02
            ),
        PARTITION tb_user_1767196800000 VALUES LESS THAN (1767196800000)
            (
            SUBPARTITION tb_user_1767196800000_01,
            SUBPARTITION tb_user_1767196800000_02
            )
        );

PARTITION BY后面部分是分区相关的SQL,表示按照create_date字段range分区,后根据tenant_id字段key分区,以上是建表时就定义好的。

如果是针对一张已存在的表建立子分区,就用下面这个,当然,建立分区的字段需要是主键,如果不是,需要先修改表结构

-- 对tb_table建立子分区
ALTER TABLE tb_user PARTITION BY RANGE (`create_date`) SUBPARTITION BY key (`tenant_id`)
    (
    -- 2025-01-01 00:00:00
    PARTITION tb_user_1735660800000 VALUES LESS THAN (1735660800000)
        (
        SUBPARTITION tb_user_1735660800000_01,
        SUBPARTITION tb_user_1735660800000_02
        ),
    -- 2026-01-01 00:00:00
    PARTITION tb_user_1767196800000 VALUES LESS THAN (1767196800000)
        (
        SUBPARTITION tb_user_1767196800000_01,
        SUBPARTITION tb_user_1767196800000_02
        )
    );

执行后,可以看到这张表的分区,是有两层级的。

在这里插入图片描述

使用

下面插入四条数据,如下:

-- 插入数据
-- 1706803200000:2024-02-02 00:00:00
-- 1706803200000:2025-02-02 00:00:00
insert into `tb_user` (tenant_id, username, password, create_date)
values ('1', '分区1', '123456', 1706803200000),
       ('2', '分区2', '12345', 1738425600000),
       ('2', '分区3', '1234', 1706803200000),
       ('1', '分区4', '123', 1738425600000);

然后敲下面的SQL,查看各个分区的情况:

-- 查看各个分区数据
select
    PARTITION_NAME,
    SUBPARTITION_NAME,
    partition_ordinal_position,
    partition_method,
    partition_expression,
    partition_description,
    table_name,
    table_rows
from information_schema.partitions
where table_name = 'tb_user';

可以看到,每个子分区里各存了一条记录,说明分区建立成功了。

在这里插入图片描述

另外

子分区,需要注意以下两点:

(1)对现有表建立分区,历史数据不会被整理到指定分区里,只有修改了历史记录的分区字段,才会被分配到指定分区里;

(2)当数据从一个分区修改到另一个分区时,会落入到子分区值相同的那个分区;


第1点,如下,先插入数据,再分区,查看分区情况,

-- 1.创建表
CREATE TABLE `tb_user`
(
    `id`          int         NOT NULL AUTO_INCREMENT,
    `tenant_id`   varchar(50) NOT NULL,
    `username`    varchar(20) DEFAULT NULL,
    `password`    varchar(20) DEFAULT NULL,
    `create_date` bigint      NOT NULL,
    PRIMARY KEY (`id`, `tenant_id`, `create_date`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4
  COLLATE = utf8mb4_general_ci COMMENT ='用户表';

-- 2.插入数据
-- 1706803200000:2024-02-02 00:00:00
-- 1738425600000:2025-02-02 00:00:00
insert into `tb_user` (tenant_id, username, password, create_date)
values ('1', '分区1', '123456', 1706803200000),
       ('2', '分区2', '12345', 1738425600000),
       ('2', '分区3', '1234', 1706803200000),
       ('1', '分区4', '123', 1738425600000);

-- 3.分区
alter table tb_user PARTITION BY RANGE (`create_date`) SUBPARTITION BY key (`tenant_id`)
    (
    PARTITION tb_user_1735660800000 VALUES LESS THAN (1735660800000)
        (
        SUBPARTITION tb_user_1735660800000_01,
        SUBPARTITION tb_user_1735660800000_02
        ),
    PARTITION tb_user_1767196800000 VALUES LESS THAN (1767196800000)
        (
        SUBPARTITION tb_user_1767196800000_01,
        SUBPARTITION tb_user_1767196800000_02
        )
    );

-- 4.查看各个分区数据
select PARTITION_NAME,
       SUBPARTITION_NAME,
       partition_ordinal_position,
       partition_method,
       partition_expression,
       partition_description,
       table_name,
       table_rows
from information_schema.partitions
where table_name = 'tb_user';

数据没有落入到分区里;

在这里插入图片描述

在这里插入图片描述

如果修改历史数据的分区字段,如下:

-- 5.修改数据
UPDATE tb_user
SET tenant_id = '2'
WHERE id = 1;

在这里插入图片描述

数据分配到了指定分区里;

在这里插入图片描述


第2点,如上,create_date是一级分区字段,tenant_id是二级分区字段,当某条记录修改了create_date,从一个分区换到了另一个分区,数据会落入到这个分区里tenant_id相同值的那个子分区。(感觉是废话,这是当然的)

总结

本文介绍了如何在MySQL中建立子分区,关于MySQL建立List、Range分区,参考下面这篇文章:

  • MySQL分区表(一)

http://www.kler.cn/a/384714.html

相关文章:

  • 兰空图床配置域名访问
  • 防火墙|WAF|漏洞|网络安全
  • C#笔记 —— 事件
  • 20241107给野火LubanCat1-BTB刷Ubuntu的预编译固件并点亮USB接口的热像仪AT600
  • day-81 打家劫舍 II
  • 数组类算法【leetcode】
  • 2024-11-07 问AI: [AI面试题] 解释推荐系统的概念
  • WorkFlow源码剖析——Communicator之TCPServer(中)
  • Hive 的数据存储单元结构
  • 存储数据库的传输效率提升-ETLCloud结合HBASE
  • 《安全软件开发框架(SSDF) 1.1:降低软件漏洞风险的建议》解读(四)
  • Java项目实战II基于SpringBoot在线课程管理系统的设计与实现(开发文档+数据库+源码)
  • 特征检测与特征匹配方法笔记+代码分享
  • Supervisor的使用-ubuntu
  • 在OceanBase 中,实现自增列的4种方法
  • 练习题 - Django 4.x HTTP 网络协议使用示例和配置方法
  • OpenSSH 安全漏洞(CVE-2023-38408)解决方案
  • leetcode hot100【LeetCode 78. 子集】java实现
  • 船体平整如镜,玛哈特矫平机为航海安全保驾护航
  • Docker Compose部署Rabbitmq(Dockerfile安装延迟队列)
  • Vue 3 单元测试与E2E测试
  • github.io出现的问题及解决方案
  • FastAPI —— 请求参数验证
  • 中酱:健康生活的先行者
  • 【SpringCloud】Kafka消息中间件
  • 操作系统面试题