postgreSQL创建表分区

postgreSQL创建表分区

1.范围分区介绍

复制代码
范围分区是根据某个列的范围来进行分区。常用于日期、时间或其他连续值类型的列。例如,按日期字段对表进行分区。

2.创建表

复制代码
创建分区时使用的复合主键,所以在代码中如果集成了mybatisplus,不要使用selectById等类似方法,而是使用QueryWrapper查询。
sql 复制代码
CREATE TABLE "public"."car" (
  "id" varchar(64) COLLATE "pg_catalog"."default" NOT NULL,
  "plate_no" varchar(255) COLLATE "pg_catalog"."default",
  "create_time" timestamp(6),
  "car_id" varchar(64) COLLATE "pg_catalog"."default",
  "height" varchar(64) COLLATE "pg_catalog"."default",
  CONSTRAINT "car_partition_pkey" PRIMARY KEY ("id","create_time")
) PARTITION BY RANGE (
  "create_time" "pg_catalog"."timestamp_ops"
)
;

3.每月创建分区函数

sql 复制代码
CREATE OR REPLACE FUNCTION "public"."monthly_partition"()
  RETURNS "pg_catalog"."void" AS $BODY$
DECLARE
    start_date TIMESTAMP;
    end_date TIMESTAMP;
    partition_name TEXT;
		partition_date TEXT;
BEGIN
    -- 获取当前日期的下个月的第一天
    start_date := date_trunc('month', CURRENT_DATE) + INTERVAL '1 month';
    -- 获取下个月的最后一天
    end_date := start_date + INTERVAL '1 month';

    -- 动态生成car分区表的名称
    partition_name := 'car_' || TO_CHAR(start_date, 'YYYY_MM');
    
    -- 创建car分区表
    EXECUTE format(
        'CREATE TABLE IF NOT EXISTS %I PARTITION OF car FOR VALUES FROM (%L) TO (%L)',
        partition_name, start_date, end_date
    );
                
                    -- 动态生成car分区表的名称
    partition_name := 'car_' || TO_CHAR(start_date, 'YYYY_MM');
    
    -- 创建car分区表
    EXECUTE format(
        'CREATE TABLE IF NOT EXISTS %I PARTITION OF car FOR VALUES FROM (%L) TO (%L)',
        partition_name, start_date, end_date
    );
		
		-- 为分区动态创建索引
        EXECUTE format(
            'CREATE INDEX IF NOT EXISTS plate_no_car_id_idx_%s ON %I (
                plate_no,
                car_id
            )',
            partition_date, partition_name
        );
    

END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;

4.调用函数

在数据库中执行一次

sql 复制代码
SELECT monthly_partition();

注:如果每月创建一个分区,可以通过定时任务调用数据库函数。(通过定时任务调用,每月执行一次)

在mapper中定义方法

java 复制代码
String createMonthlyPartition();

然后在xml中编写sql

xml 复制代码
    <select id="createMonthlyPartition" statementType="CALLABLE" resultType="java.lang.String" >
        {call monthly_partition()}
    </select>

5.历史数据按月创建分区

如果旧表没有创建分区,重新建表分区后,必须要根据时间字段创建分区后才能导入数据。创建分区可以执行下面脚本。(只需执行一次)

sql 复制代码
DO $$
DECLARE
    start_date DATE := '2024-01-01';  -- 起始日期,建议设置为月份的第一天
    current_date DATE := CURRENT_DATE; -- 当前日期
    partition_name TEXT;
    start_time TIMESTAMP;
    end_time TIMESTAMP;
    d DATE;  -- 声明变量 d 为 DATE 类型
BEGIN
    -- 使用 generate_series 生成从 start_date 到 current_date 的月份范围
    FOR d IN 
        SELECT date_trunc('month', generate_series(start_date, current_date, '1 month'::INTERVAL))
    LOOP
        -- 为每个月生成对应的时间范围
        start_time := d;
        end_time := d + INTERVAL '1 month';

        -- 动态生成分区名称
        partition_name := 'car_' || TO_CHAR(d, 'YYYY_MM');

        -- 创建分区
        EXECUTE format(
            'CREATE TABLE IF NOT EXISTS %I PARTITION OF car 
             FOR VALUES FROM (%L) TO (%L)',
            partition_name, start_time, end_time
        );
    END LOOP;
END $$;

6.查看、删除分区索引

查看分区索引

sql 复制代码
SELECT * FROM pg_indexes WHERE tablename = 'car_2025_01';

删除分区索引。plate_no_car_id_idx_为索引名

sql 复制代码
DROP INDEX IF EXISTS plate_no_car_id_idx_;
相关推荐
我命由我1234518 分钟前
Kotlin 数据容器 - List(List 概述、创建 List、List 核心特性、List 元素访问、List 遍历)
java·开发语言·jvm·windows·java-ee·kotlin·list
武子康2 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
-SGlow-4 小时前
MySQL相关概念和易错知识点(2)(表结构的操作、数据类型、约束)
linux·运维·服务器·数据库·mysql
明月5665 小时前
Oracle 误删数据恢复
数据库·oracle
YuTaoShao5 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
源码_V_saaskw5 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
超浪的晨6 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发
双力臂4046 小时前
Spring Boot 单元测试进阶:JUnit5 + Mock测试与切片测试实战及覆盖率报告生成
java·spring boot·后端·单元测试
♡喜欢做梦6 小时前
【MySQL】深入浅出事务:保证数据一致性的核心武器
数据库·mysql
遇见你的雩风6 小时前
MySQL的认识与基本操作
数据库·mysql