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

PostgreSQL表分区简单介绍和操作方法

一、什么是表分区?它和分库分表有什么区别?

1.1 什么是表分区(Table Partitioning)?

表分区是数据库的一种物理设计技术,它将一个大表从逻辑上视为一个整体,但从物理上拆分成多个子表(分区),每个分区存储一部分数据。

  • 逻辑上:你仍然像操作一张表一样查询它
  • 物理上:数据分散在多个子表中,按规则存储
  • ✅ 举个例子:
    jgpt_jzd_test 按年份拆成 p2023p2024p2025 三个分区,查询时仍用 SELECT * FROM jgpt_jzd_test,但数据库只扫描相关分区。

1.2 表分区 vs 分库分表:关键区别

对比项表分区分库分表
实现层级数据库内部(单库)应用层或中间件(跨库)
透明性高(应用无感知)低(需改代码)
管理复杂度低(自动路由)高(需路由规则)
事务支持完整支持跨库事务复杂
适用场景单表过大(百万~亿级)数据量极大(TB级+)
技术栈PostgreSQL、MySQL 8.0+ShardingSphere、MyCat

简单说

  • 表分区是“数据库帮你拆”
  • 分库分表是“你自己写代码拆”

二、表分区的优缺点与使用场景

✅ 优点

优势说明
查询性能提升分区剪枝(Partition Pruning)自动跳过无关分区
数据管理高效删除旧数据从 DELETE 变为 DROP PARTITION(秒级)
维护更方便可对单个分区做 VACUUMANALYZE、备份
I/O 分散不同分区可分布到不同磁盘(高级用法)

❌ 缺点

缺点说明
全表扫描变慢需扫描所有分区,元数据开销增加
分区键固定一旦选定(如 gmt_create),不能更改
管理复杂度上升需定期创建新分区
不支持主键跨分区主键必须包含分区键

三、PostgreSQL 表分区的三种方式

PostgreSQL 支持三种分区策略:

1. Range 分区(按范围)

  • 适用:时间、数值范围
  • 示例:按 gmt_create 按年/月分区
  • 语法
    PARTITION BY RANGE (gmt_create)

2. List 分区(按枚举值)

  • 适用:固定分类,如省份、状态
  • 示例:按 province 分区
  • 语法
    PARTITION BY LIST (province)

3. Hash 分区(按哈希值)

  • 适用:数据均匀分布,无明显查询模式
  • 示例:按 id 哈希分 4 份
  • 语法
    PARTITION BY HASH (id)

四、实战:jgpt_jzd_test 表分区操作全流程

将 3000 万+ 的 jgpt_jzd_test 表改造为按年分区的分区表。

步骤 1:创建分区主表

-- 创建主表(逻辑表,不存数据)
CREATE TABLE jgpt_jzd_test_partitioned (id                    varchar(32),jzdbh                 varchar(255),xzb                   varchar(255),yzb                   varchar(255),htxxid                varchar(255),gmt_create            timestamp(6) NOT NULL,  -- 必须 NOT NULLgmt_modified          timestamp(6),del_flag              varchar,created_user_id       varchar(255),created_user          varchar(255),last_modified_user_id varchar(255),last_modified_user    varchar(255),dkh                   varchar(255),dkms                  varchar(255),batchnum              varchar(255)
) PARTITION BY RANGE (gmt_create);

步骤 2:创建子分区(按年)

-- 2023 年分区
CREATE TABLE jgpt_jzd_test_p2023 PARTITION OF jgpt_jzd_test_partitionedFOR VALUES FROM ('2023-01-01') TO ('2024-01-01');-- 2024 年分区
CREATE TABLE jgpt_jzd_test_p2024 PARTITION OF jgpt_jzd_test_partitionedFOR VALUES FROM ('2024-01-01') TO ('2025-01-01');-- 2025 年分区
CREATE TABLE jgpt_jzd_test_p2025 PARTITION OF jgpt_jzd_test_partitionedFOR VALUES FROM ('2025-01-01') TO ('2026-01-01');

步骤 3:迁移数据

-- 从旧表插入到新分区表(自动路由)
INSERT INTO jgpt_jzd_test_partitioned 
SELECT * FROM jgpt_jzd_test;

步骤 4:创建索引

-- 在主表创建索引,所有分区自动继承
CREATE INDEX idx_jgpt_jzd_test_htxxid ON jgpt_jzd_test_partitioned (htxxid);

步骤 5:切换表名(原子操作)

-- 1. 备份原表
ALTER TABLE jgpt_jzd_test RENAME TO jgpt_jzd_test_backup;-- 2. 新表启用原名
ALTER TABLE jgpt_jzd_test_partitioned RENAME TO jgpt_jzd_test;

✅ 至此,jgpt_jzd_test 已是分区表!

五、验证表分区是否成功

1. 查看分区结构


-- 查询系统表
SELECT inhrelid::regclass AS child_table,inhparent::regclass AS parent_table
FROM pg_inherits 
WHERE inhparent = 'jgpt_jzd_test'::regclass;

2. 验证分区剪枝是否生效

explain SELECT COUNT(*) FROM jgpt_jzd_test WHERE gmt_create >= '2025-01-01' AND gmt_create < '2026-01-01';

可以看到只查询了jgpt_jzd_test_p2025一张分区表

六、安全删除分区:DETACH vs DROP(关键区别)

在表分区的日常维护中,删除历史数据是一个高频操作。PostgreSQL 提供了两种方式来“移除”分区,但它们的安全性、可逆性和使用场景完全不同。

我们以 jgpt_jzd_test_p2024 分区为例,对比两种操作:

1. DETACH PARTITION —— 安全的“解绑”操作

ALTER TABLE jgpt_jzd_test_partitionedDETACH PARTITION jgpt_jzd_test_p2024;
✅ 操作特点:
  • 数据不会丢失jgpt_jzd_test_p2024 表变成一个独立的普通表
  • 主表 jgpt_jzd_test_partitioned 不再包含该分区的数据
  • 可随时对 jgpt_jzd_test_p2024 进行查询、导出、备份或重新挂载
🎯 适用场景:
  • 需要归档数据
  • 删除前做审计或备份
  • 不确定是否永久删除
-- 确认无误后,再删除
DROP TABLE jgpt_jzd_test_p2024;

推荐做法DETACH,再 DROP,避免误删

2. DROP PARTITION —— 永久删除

ALTER TABLE jgpt_jzd_test_partitionedDROP PARTITION jgpt_jzd_test_p2024;
❌ 操作特点:
  • 数据立即永久丢失!无法通过 DROP 回滚
  • 相当于执行了 DROP TABLE,文件被物理删除
  • 无法恢复(除非有数据库备份)
⚠️ 适用场景:
  • 确认数据不再需要
  • 紧急释放磁盘空间
  • 自动化脚本中已确认安全

对比总结

操作数据是否保留是否可逆安全性推荐使用场景
DETACH PARTITION✅ 保留✅ 可逆所有删除操作的首选
DROP PARTITION❌ 丢失❌ 不可逆确认永久删除

七、自己的理解

1.表分区之后,你在datagrip或navicat里面看到的还是一张表,数据也都在这张表里,但实际上这张表是主表,没有存储数据。

2.数据实际存储在分区表里,例如jgpt_jzd_test_p2024,因此代码里面是可以直接调用这张表的

3.平时基本不用管分区表,正常使用主表就行了,比如你插入数据,直接往jgpt_jzd_test插入,数据库会根据你的gmt字段自动插入到相应的分区表里面,平时使用基本是无感的

✅ 总结:我的认知升级

旧认知新认知
分区就是“拆表”分区是“逻辑统一,物理分离”
数据存在主表主表是“空壳”,数据在分区
只能查主表可直查分区,性能更优
分区很复杂日常使用完全无感
http://www.dtcms.com/a/407101.html

相关文章:

  • 建设网站费用评估浙江省特种作业证查询官网
  • Charles在安全测试中的应用,接口漏洞验证与敏感数据检测
  • NAT、代理服务与内网穿透详解
  • 为什么有时候 reCAPTCHA 通过率偏低,常见原因有哪些
  • 外出也能随时 SSH 访问内网 Linux,ZeroNews 提供公网域名直达
  • 基于vue的咖啡销售系统28zz1(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
  • LoadBalancer完整学习笔记:简介、原理与自定义
  • 网站建设英文怎么说洛阳php网站开发
  • 图片转文字(PDF转word,图片转word等)
  • 网站维护一年多少费北京网站建设培训
  • 让风恒定:在 unordered 的荒原上种下一棵常数级的树
  • 图书网站建设实训总结前端培训心得
  • 【Spring Cloud Alibaba】Seata(一)
  • 仓颉编程语言的stdx包介绍及使用
  • 长沙网站制作方法wordpress获得所有分类
  • 无限空间 网站网站新闻页面无法翻页
  • 民族团结 网站建设wordpress底部版权插件
  • Markdown转PDF工程化实现含图片支持与样式控制
  • Linux下安装Kafka 3.9.1
  • kafka vs rocketmq
  • 1.DHCP服务器
  • 河南网站备案代理苏州专业网站建设公司
  • 电商网站seo公司网页怎么做成网站
  • 与TCP相比,UDP有什么优缺点?
  • 从0到1制作一个go语言服务器 (一) 配置
  • 沙姆定律原理/公式推导
  • leetcode 98 验证二叉搜索树
  • 国外外包网站天津百度搜索排名优化
  • 中国建设银行网站企业网银收费怎么在外国网站上找产品做跨境电商
  • 合肥网站优化搜索怎么做网站优化 site