PostgreSQL分区表,实战细节满满

news2024/11/25 19:27:23

📢📢📢📣📣📣
作者:IT邦德
中国DBA联盟(ACDU)成员,10余年DBA工作经验,
Oracle、PostgreSQL ACE
CSDN博客专家及B站知名UP主,全网粉丝10万+
擅长主流Oracle、MySQL、PG、高斯及Greenplum备份恢复,
安装迁移,性能优化、故障应急处理

文章目录

  • 前言
    • 1.何为分区表
    • 2.分区表的特点
    • 3.声明分区表分类
      • 3.1 range分区
      • 3.2. list分区
      • 3.3 hash分区
      • 3.4 混合分区
    • 4.继承分区表

前言

本文详细的阐述了PostgreSQL分区表的细节,分享给大家

1.何为分区表

分而治之是分区表最大的特点,将表数据分成更小的物理分片,减少搜索范围,以此可以查询提高性能。分区表是关系型数据库中比较常见的对大表的优化方式,数据库管理系统一般都提供了分区管理,而业务可以直接访问分区表而不需要调整业务架构,当然好的性能需要合理的分区访问方式。

2.分区表的特点

分区的具体好处是:改善查询性能、增强可用性、维护方便、均衡I/O

image.png

3.声明分区表分类

声明分区也叫原生分区,从PG10版本开始支持,相当于“官方支持”的分区表,也是最为推荐的分区方式。

声明分区只支持4种分区方式:range分区、list分区、hash分区、混合分区表

3.1 range分区

range分区表以范围进行分区,分区边界为[t1,t2)


--创建主表
CREATE TABLE PUBLIC.RANPARTITION1
(
    id int,
    name varchar(50) NULL, 
    DATE_CREATED timestamp NOT NULL DEFAULT now()
) PARTITION BY RANGE(DATE_CREATED);


alter table public.RANPARTITION1 add primary key(id,DATE_CREATED)

--创建分区表
create table RANPARTITION1_202401 partition of RANPARTITION1 for values from ('2024-01-01 00:00:00') to ('2024-02-01 00:00:00');

create table RANPARTITION1_202402 partition of RANPARTITION1 for values from ('2024-02-01 00:00:00') to ('2024-03-01 00:00:00');

--往分区表添加一些数据
INSERT INTO RANPARTITION1  
SELECT random() * 10000, md5(g::text),g 
FROM generate_series('2024-01-01'::date, '2024-02-28'::date, '1 minute') as g;

range分区的from t1 to t2,为[t1,t2)范围,下边界包含上边界不包含。

查看分区表,每个分区也是单独的表
postgres=# \d+ RANPARTITION1

postgres=#  \d+ RANPARTITION1_202401

分区上的主键、索引、字段null/CHECK约束自动创建。
由于分区也是独立的表,约束和索引也可以单独在分区上创建。

3.2. list分区

list分区以指定的分区值将数据存放到对应的分区上


--创建主表
CREATE TABLE part_list (
    city_id      int not null,
    name         varchar(30),
    population   int
) PARTITION BY LIST (name);

Create  index  part_list_idx on part_list  (name);

--创建分区表
CREATE TABLE p1_list PARTITION OF part_list FOR VALUES IN ('fujian', 'zhejiang');
CREATE TABLE p2_list PARTITION OF part_list FOR VALUES IN ('shandong', 'jiangxi');

-插入数据

insert into part_list (city_id,name,population) values(1,'fujian',10);
insert into part_list (city_id,name,population) values(2,'zhejiang',20);   
insert into part_list (city_id,name,population) values(3,'shandong',10);
insert into part_list (city_id,name,population) values(4,'jiangxi',20); 

--查看数据
SELECT tableoid::regclass,* FROM part_list;

list分区表可以创建null分区

3.3 hash分区

hash分区将数据散列存储在各个分区上,以打散热点数据存放到对应的分区上,然后把满足条件的行存放在该分区中,最常见的是平均的把数据放在不同的分区

--创建主表
CREATE TABLE part_hash 
(order_id int,
name varchar(10)) 
PARTITION BY HASH (order_id);

Create  index  part_hash_idx on part_hash  (order_id);

--创建分区表

CREATE TABLE p1_hash PARTITION OF part_hash FOR VALUES WITH (MODULUS 3, REMAINDER 0);
CREATE TABLE p2_hash PARTITION OF part_hash FOR VALUES WITH (MODULUS 3, REMAINDER 1);
CREATE TABLE p3_hash PARTITION OF part_hash FOR VALUES WITH (MODULUS 3, REMAINDER 2);

每个Hash分区需指定"模"(modulus)和"余"(remainder),
数据在哪个分区(partition index)的计算公式:
partition index = abs(hashfunc(key)) % modulus

--插入数据
insert into part_hash values(generate_series(1,10000),'a');

--查询数据
SELECT tableoid::regclass,count(*) FROM part_hash  group by tableoid::regclass;

--查看执行计划
explain select * from part_hash where order_id=1000;

3.4 混合分区

分区下面也可以建立分区构成级联模式,子分区可以有不同的分区方式,这样的分区成为混合分区。

image.png

--创建一个混合分区:

create table part_1000(id bigserial not null,name varchar(10),createddate timestamp) partition by range(createddate);
create table part_2401 partition of part_1000 for values from ('2024-01-01 00:00:00') to ('2024-02-01 00:00:00') partition by list(name) ;
create table part_2402 partition of part_1000 for values from ('2024-02-01 00:00:00') to ('2024-03-01 00:00:00') partition by list(name) ;
create table part_2403 partition of part_1000 for values from ('2024-03-01 00:00:00') to ('2024-04-01 00:00:00') partition by list(name) ;
create table part_3001 partition of part_2401 FOR VALUES IN ('abc');
create table part_3002 partition of part_2401 FOR VALUES IN ('def');
create table part_3003 partition of part_2401 FOR VALUES IN ('jkl');

\d+只能看到下一级的分区

\d+ part_1000
\d+ part_2001

--此时插入一条数据
insert into part_1000 values(random() * 10000,'abc','2024-01-01 08:00:00');

声明分区特性小结

• 分区表的分区本身也是表,这个特性比较特殊。这不仅仅造成pg可以灵活的操作子分区,更重要的是功能和特性上的影响。
• truncate,vacuum,analyze分区表会执行所有分区。truncate only不能在父表上执行,但可以在存数据的子表上执行,仅清除这个子分区。
• range,hash分区的分区键可以有多个列,list分区的分区键只能是单个列或表达式。
• 分区父表本身是空的,最底层子分区可以存储数据
• default分区表会接收不在声明的范围中的数据;如果没有default分区,插入范围外的数据会直接报错
• 如果要新增分区,需要注意default分区中是否有这个新增分区的数据
• partition of创建的分区会自动创建分区表上的索引、约束、行级触发器
• attach不会处理任何索引、约束等等对象

4.继承分区表

继承分区也是官方支持的,它利用了PGSQL的继承表特性来实现分区表的功能。继承分区表会比声明分区表更灵活。 继承分区表的实现需要到了PGSQL中的2个功能:继承表和写入重定向。写入重定向可以通过rule或者trigger来实现。

1.创建父表
CREATE TABLE measurement (
    city_id         int not null,
    logdate         date not null,
    peaktemp        int,
    unitsales       int
);

2.创建继承表,指定约束范围
CREATE TABLE measurement_202409 (
    CHECK ( logdate >= DATE '2024-09-01' AND logdate < DATE '2024-10-01' )
) INHERITS (measurement);
CREATE TABLE measurement_202410 (
    CHECK ( logdate >= DATE '2024-10-01' AND logdate < DATE '2024-11-01' )
) INHERITS (measurement);

3.创建规则或触发器,将插入数据重定向到对应的继承表中
CREATE OR REPLACE FUNCTION measurement_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF ( NEW.logdate >= DATE '2024-09-01' AND
         NEW.logdate < DATE '2024-10-01' ) THEN
        INSERT INTO measurement_202409 VALUES (NEW.*);
    ELSIF ( NEW.logdate >= DATE '2024-10-01' AND
            NEW.logdate < DATE '2024-11-01' ) THEN
        INSERT INTO measurement_202410 VALUES (NEW.*);
    ELSE
        RAISE EXCEPTION 'Date out of range.  Fix the measurement_insert_trigger() function!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

CREATE TRIGGER insert_measurement_trigger
    BEFORE INSERT ON measurement
    FOR EACH ROW EXECUTE FUNCTION measurement_insert_trigger();


--插入范围外的数据会报错
=> insert into measurement values(1001, now() - interval '80' day  ,1,1);

--插入数据会重定向到子表上
=> insert into measurement values(1001,now(),1,1);


除了触发器,PGSQL还可以用rule来重定向插入。 rule语句参考
CREATE RULE measurement_insert_202409 AS
ON INSERT TO measurement WHERE
    ( logdate >= DATE '2024-09-01' AND logdate < DATE '2024-10-01' )
DO INSTEAD
    INSERT INTO measurement_202410 VALUES (NEW.*);
CREATE RULE measurement_insert_202410 AS
ON INSERT TO measurement WHERE
    ( logdate >= DATE '2024-10-01' AND logdate < DATE '2024-11-01' )
DO INSTEAD
    INSERT INTO measurement_202410 VALUES (NEW.*);

规则和触发器的差异:
• rule性能相较trigger更差,但在批量插入时,由于rule只有一次检查,性能会比trigger更好,但其他情况下trigger更好
• COPY不会触发rule,但会触发trigger。rule时可以将数据直接COPY到子表中
• 当插入范围外数据时,rule会将数据插入到父表中,trigger则会直接报错

4.分区的索引一般都是必不可少,继承表的索引需要手动在子表上创建
CREATE INDEX idx_measurement_202409_logdate ON measurement_202409 (logdate);
CREATE INDEX idx_measurement_202410_logdate ON measurement_202410 (logdate);

将一个继承分区做成普通表
ALTER TABLE measurement_202409 NO INHERIT measurement;

将一个含有数据的普通表当成子表加入到继承分区表中

CREATE TABLE measurement_202411
(LIKE measurement INCLUDING DEFAULTS INCLUDING CONSTRAINTS);
ALTER TABLE measurement_202411 ADD CONSTRAINT measurement_202411_logdate_check  
CHECK ( logdate >= DATE '2024-11-01' AND logdate < DATE '2024-12-01' );
--insert into measurement_202411 values(2001,'20241110',3,3);
ALTER TABLE measurement_202411 INHERIT measurement;

继承分区表特性小结

• 继承分区要比声明分区更灵活,但一些声明分区的特性也无法使用
• 子表会继承父表上的约束,所以如果不是全局约束不要在父表上设置
• 索引不会继承,索引只能在子表上一个个地创建
• 声明分区只能有range、list、hash分区,继承分区可以更多,也可以是自定义的分区方式。
• 删除一个子表不会导致触发器失效。PGSQL没有像ORACLE那样失效对象的概念(索引有失效的概念)
• 一般来说使用trigger的插入重定向比rule效率更好
• 新增分区时,如果触发器函数中没有该分区的规则,则需要更新触发器函数。
• 继承分区可以多重继承
• 约束排除不能在执行时进行排除,所以建议使用固定值进行查询
• 使用继承分区表时,同样不要创建太多的子分区

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2193307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

茄子病虫害数据集。四类:果肉腐烂、蛀虫、健康、黄斑病。4000张图片,已经按照8:2的比例划分好训练集、验证集 txt格式 含类别yaml文件 已经标注好

茄子病虫害数据集。可用于筛选茄子品质、质量&#xff0c;训练采摘机器人视觉算法模型……数据集大部分图片来源于真实果园拍摄的图片&#xff08;生长在果树之上的&#xff09;&#xff0c;图片分辨率高&#xff0c;数据集分为四类&#xff1a;果肉腐烂、蛀虫、健康、黄斑病。…

如何使用ssm实现基于Java的民宿预订管理系统的设计与实现

TOC ssm773基于Java的民宿预订管理系统的设计与实现jsp 绪论 1.1课题研究背景意义 随着科技的发展&#xff0c;计算机的应用&#xff0c;人们的生活方方面面都和互联网密不可分。计算机的普及使得人们的生活更加方便快捷&#xff0c;网络也遍及到我们生活的每个角落&#x…

Vue - 打包部署

vscode找到NPM脚本&#xff0c;点击build。 目录下出现dist目录则表示安装成功。 安装Nginxnginx: download 目录用途conf配置文件目录html静态资源文件目录logs日志文件目录temp临时文件目录 将刚刚打包好的文件放到html目录下。 点击nginx.exe&#xff0c;用localhost:默认…

Windows应急响应-QQ巨盗病毒

文章目录 病毒背景样本分析开启监控感染病毒分析病毒行为C盘文件监控D盘文件监控进程监控排查服务排查启动项排查 查杀1.杀掉进程2.异常服务3.映像劫持处理4.hosts文件处理5.D盘文件删除6.其他异常排查 重启排查 病毒背景 简介&#xff1a;Win32.PSWTroj.QQPass&#xff0c;名…

模拟退火算法简介

什么是模拟退火算法&#xff1f; 模拟退火算法&#xff08;Simulated Annealing&#xff0c;SA&#xff09;是一种基于随机化搜索的优化算法&#xff0c;灵感来源于金属退火过程。在金属制造中&#xff0c;金属被加热到高温并缓慢冷却&#xff0c;这一过程可以减少内部缺陷&am…

【前端】-音乐播放器(源代码和结构讲解,大家可以将自己喜欢的歌曲添加到数据当中,js实现页面动态显示音乐)

前言&#xff1a;音乐播放器是前端开发中的一个经典项目&#xff0c;通过它可以掌握很多核心技术&#xff0c;如音频处理、DOM操作、事件监听、动画效果等。这个项目不仅能提升前端开发的技能&#xff0c;还能让开发者深入理解JavaScript与HTML的协同作用。 页面展示&#xff1…

精准选择大模型:消费品行业的营销与体验创新之路

在消费品行业&#xff0c;大模型技术的引入正逐渐从一个新兴趋势转变为行业标配。随着人工智能的快速发展&#xff0c;特别是OpenAI等领军企业推出的创新技术&#xff0c;如Sora&#xff0c;大模型在市场营销、消费者行为分析、个性化推荐等方面展现出巨大潜力。然而&#xff0…

基础算法(5)——位运算

1. 常见位运算总结 1) 基础位运算 2) 给一个数 n&#xff0c;确定它的二进制表示中的第 x 位是 0 还是 1 3) 将一个数 n 的二进制表示的第 x 位修改成 1 4) 将一个数 n 的二进制表示的第 x 位修改成 0 5) 位图的思想 位图的本质就是 哈希表 6) 提取一个数 n 二进制表示中最右…

如 有 任 何 问 题 ,请 及 时 联 系 我 们 反 馈 !

如有任何问题&#xff0c; 请及时联系我们反馈 !https://support.qq.com/products/671606 如有任何问题&#xff0c; 请及时联系我们反馈 !

Bluetooth Channel Sounding中关于CS Procedure的详细介绍

目录 BLE CS 过程定义&#xff1a; BLE CS 过程的组成部分 开始一个BLE CS 过程 与BLE CS过程相关的参数设置 BLE CS 过程定义&#xff1a; BLE 的CS特性包含一组LL层和空口协议的组合过程&#xff0c;该过程可以使得两个BLE 设备以紧密互锁的方式&#xff0c;在多个信道上…

Ubuntu 上安装 MySQL 并且实现远程登录

目录 1. 安装MySQL 2. 安全配置MySQL 3. 配置MySQL远程登录 3.1. 允许远程连接 3.2. 重启MySQL服务 3.3. 为用户分配远程访问权限 进入MySQL后&#xff0c;执行以下命令&#xff1a; 3.4. 创建新用户 3.5. 授予权限 3.6. 刷新权限 3.7. 退出 MySQL 控制台 4. 配置防火…

2024.9月29日~10月6日 SSM框架项目-《电信资费管理系统》

一、数据库介绍&#xff1a; 1、account&#xff1a;帐务信息表 2、admin_info&#xff1a;管理员信息表 3、admin_role&#xff1a;管理员角色信息表 4、cost&#xff1a;资费信息表 5、privilege_info&#xff1a;权限信息表 6、role_info&#xff1a;角色信息表 7、role_pri…

在CentOS7上安装mysql

目录 1.下载安装文件 2.上传到CentOS7上 3.解压MySQL文件 4.清理系统中残留的MySQL 5.安装MySQL 6.启动MySQL 并 设置开机自启动 7.查找临时密码&#xff0c;并修改密码 注意&#xff1a; 教程&#xff1a;在Linux上安装mysql&#xff08;超详细版&#xff09;_哔哩哔哩…

人工智能新闻和发展 (24001)- By 10/4/2024

1. 谷歌增强了搜索中的人工智能&#xff0c;允许对图像进行语音提问。 Google adding AI to answer voiced questions about images | AP NewsGoogle is pumping more artificial intelligence into its search engine. New features will enable people to voice questions a…

[C#]使用onnxruntime部署yolov11-onnx实例分割模型

【官方框架地址】 https://github.com/ultralytics/ultralytics.git 【算法介绍】 在C#中使用ONNX Runtime部署YOLOv11-ONNX实例分割模型&#xff0c;涉及到模型的加载、数据预处理、模型推理和后处理几个关键步骤。 首先&#xff0c;需要确保已经安装了ONNX Runtime的NuGe…

【数据结构】【链表代码】随机链表的复制

/*** Definition for a Node.* struct Node {* int val;* struct Node *next;* struct Node *random;* };*/typedef struct Node Node; struct Node* copyRandomList(struct Node* head) {if(headNULL)return NULL;//1.拷贝结点&#xff0c;连接到原结点的后面Node…

[Linux] 进程创建、退出和等待

标题&#xff1a;[Linux] 进程创建、退出和等待 个人主页水墨不写bug &#xff08;图片来源于AI&#xff09; 目录 一、进程创建fork&#xff08;&#xff09; 1&#xff09; fork的返回值&#xff1a; 2&#xff09;写时拷贝 ​编辑3&#xff09;fork常规用法 4&#xff…

目标侦测划分数据集代码--->voc

代码如下&#xff1a; import glob import os import random import shutil # 划分比例 p3/4#训练集 xmlpathE:\\shujuji\\MASK\\Annotations\\* imgpathE:\\shujuji\\MASK\\JPEGImages\\* xmlpathsglob.glob(xmlpath) imgpathsglob.glob(imgpath) my_list[i for i in range(l…

MATLAB图像去雾系统

应用背景 现在工业发展迅速&#xff0c;产生的废气很严重&#xff0c;导致雾霾厉害&#xff0c;现在虽然有硬件来拍摄&#xff0c;可以清晰化视野&#xff0c;但是硬件成本昂贵&#xff0c;急需寻求一种算法来帮助雾霾的清晰处理。显得经济。 采用算法原理 本文采用全局直方…

走进异常类的世界,自定义业务异常类实现指南

接下来这篇文章&#xff0c;小编将带领大家走进异常类的世界&#xff0c;探索异常类的奥秘。 引言 学习Java异常类&#xff0c;需掌握其基础概念&#xff0c;如try-catch语句、throw与throws关键字。通过实例理解异常层次结构&#xff0c;区分已检查与未检查异常。实践编写自定…