PostgreSQL的奥秘:表结构、TOAST与大对象

PostgreSQL(以下简称PSQL)因其灵活性和强大的功能深受欢迎。本文将详细介绍PSQL的内部结构,特别是页面缓冲机制,包括表结构、TOAST技术、大对象(BLOB/CLOB),以及页面缓冲表的工作原理。同时,我们将探讨TOAST与大对象存储的区别与应用场景,并结合优化建议提升数据库性能。


1. PostgreSQL表结构

在PSQL中,表由固定大小的页面(Page)组成,每个页面通常为8KB。页面是数据读写的最小单位,其内部结构包括:

1.1 页面内部结构

  • 首部数据:存储页面的元数据信息。

    • pd_lsn(Log Sequence Number):表示页面最近一次变更的日志序列号(LSN)。
      示例:假设我们执行一个更新操作,将一个用户的名字从“John”改为“Jonathan”。这个操作会生成一个新的LSN,并记录在受影响页面的pd_lsn中,确保可以在崩溃后通过日志恢复该操作。

    • pd_checksum:页面校验和,用于验证页面的完整性。
      示例:当读取页面时,PSQL会计算页面的校验和并与pd_checksum进行比较,以确保数据未被损坏。

    • pd_lower:指向元组指针数组的末尾位置。
      示例:在一个页面中,pd_lower指向元组指针数组的末尾。如果我们插入一个新行,pd_lower将向下移动。

    • pd_upper:指向最新元组的起始位置。
      示例:如果我们在页面中添加一个新元组,pd_upper将向上移动,标识空闲空间的减少。

  • 指向元组的指针:用于定位页面中的各个元组(行数据)。

  • 空闲空间:用于存储新的元组或更新现有元组。

  • 元组数据:实际的行数据,不能跨页面存储。

PSQL采用32位寻址, 所以PSQL单表最大容量为2^32*8K,为32TB
在这里插入图片描述

1.2 表结构优化建议

为了提升表的性能和存储效率,以下是一些优化建议:

  1. 适当的索引设计

    • 为频繁查询的列创建索引,但要避免为每个列都创建索引,以免增加写操作的开销。
    • 使用覆盖索引(Covering Index)来减少对表的访问次数,特别是在读取密集型应用中。

    示例:假设有一个用户表users,经常通过email查询用户信息,可以为email列创建索引:

    CREATE INDEX idx_users_email ON users(email);
    
  2. 合理的表分区

    • 对于大表,考虑使用表分区(Partitioning)来提高查询性能。根据常用查询条件对表进行分区,例如按日期分区以加快时间范围查询。

    示例:按年份分区存储日志数据:

    CREATE TABLE logs (id SERIAL PRIMARY KEY,log_date DATE,message TEXT
    ) PARTITION BY RANGE (log_date);CREATE TABLE logs_2023 PARTITION OF logs FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');
    CREATE TABLE logs_2024 PARTITION OF logs FOR VALUES FROM ('2024-01-01') TO ('2025-01-01');
    
  3. 使用合适的数据类型

    • 根据数据的实际用途选择合适的数据类型。例如,对于固定长度的字符串,使用CHAR(n)而不是VARCHAR(n)
    • 使用INTEGER代替BIGINT,除非确实需要存储非常大的整数。

    示例:如果用户的姓氏长度固定为50个字符,可以使用:

    CREATE TABLE users (id SERIAL PRIMARY KEY,first_name VARCHAR(100),last_name CHAR(50)
    );
    
  4. 优化数据存储格式

  • 通过配置合适的fillfactor来优化页面利用率。较低的填充因子可以减少页面分裂,但会增加磁盘空间使用。

  • fillfactor 的值是一个百分比,范围从 10 到 100,表示数据库在每个数据页面中预留的空间比例。例如:
    fillfactor=100 表示页面将被完全填满,不预留空闲空间。
    fillfactor=70 表示页面将在 70% 的空间被填满时停止插入数据,剩余 30% 的空间被保留。
    使用 fillfactor 可以帮助控制表或索引的更新效率,特别是在有大量更新的表或索引中:

  • 高更新表:当表中有频繁的更新操作时,设置较低的 fillfactor 会为未来的更新操作留出足够的空间,避免数据行更新时需要进行页面拆分(Page Split)或在页面之间移动数据,从而提高性能。

  • 只读表:对于插入后不经常更新的表,可以将 fillfactor 设置为 100,最大化页面的利用率,从而减少磁盘占用。

    示例:为频繁更新的表设置较低的fillfactor

    CREATE TABLE orders (id SERIAL PRIMARY KEY,order_data JSONB
    ) WITH (fillfactor = 70);
    
  1. 定期进行VACUUM操作

    • 定期执行VACUUMANALYZE命令,以清理死元组并更新统计信息,确保查询优化器能够生成高效的查询计划。

    示例

    VACUUM ANALYZE;
    
  2. 监控和优化查询

    • 使用EXPLAIN命令分析查询计划,识别潜在的性能瓶颈。
    • 使用查询日志和慢查询日志来监控性能,识别需要优化的查询。

    示例

    EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'example@example.com';
    

2. TOAST技术

TOAST(The Oversized-Attribute Storage Technique)用于处理超大数据属性。PSQL通过TOAST技术将大数据分成较小块存储,具体策略如下:

  • 压缩:如果策略允许,TOAST优先对数据进行压缩,尤其是小于TOAST_TUPLE_THRESHOLD(约2KB)的数据。
  • 行外存储:对于超过2KB的数据,启用行外存储。
  • 30位长度限制:在TOAST中,单个字段的最大大小实际上受到30位偏移量的限制。这是因为TOAST使用一个30位的整数来表示这些块的偏移量。理论上,这意味着最大字段大小大约是1GB

示例:假设我们有一个包含大量文本的列,如文章内容。默认情况下,PSQL会尝试压缩并存储超过2KB的部分在TOAST表中。

CREATE TABLE articles (id SERIAL PRIMARY KEY,title VARCHAR(255),content TEXT
);

content列的内容超过2KB时,TOAST会自动处理,将数据分块存储在TOAST表中。
在这里插入图片描述

2.1 TOAST策略

TOAST策略包括:

  • PLAIN:避免压缩和行外存储。
  • EXTENDED:允许压缩和行外存储(默认策略)。
  • EXTERNAL:允许行外存储,但禁止压缩。
  • MAIN:允许压缩,但禁止行外存储。

示例:为content列设置不同的TOAST策略:

CREATE TABLE articles_plain (id SERIAL PRIMARY KEY,title VARCHAR(255),content TEXT
) WITH (toast_tuple_target = 2048);ALTER TABLE articles_plain ALTER COLUMN content SET STORAGE EXTERNAL;CREATE TABLE articles_extended (id SERIAL PRIMARY KEY,title VARCHAR(255),content TEXT
) WITH (toast_tuple_target = 2048);ALTER TABLE articles_extended ALTER COLUMN content SET STORAGE EXTENDED;

3. 大对象(BLOB/CLOB)存储

BLOB(Binary Large Object)和CLOB(Character Large Object)用于存储大型二进制和文本数据。

  • 最大容量:每个对象最大可达4TB。
  • 存储位置:数据存储在pg_largeobject系统表中。
  • 数量限制:最多支持 (2^{32}) 个大对象,因为OID(对象标识符)为32位。

示例:如果我们要存储一个4GB的视频文件,可以将其作为BLOB存储在PSQL中,每段数据被分成多个片段存储在pg_largeobject中。

BEGIN;
-- 创建大对象
SELECT lo_create(0) AS oid;-- 假设获取的oid是 12345
-- 打开大对象
SELECT lo_open(12345, 131072) AS fd;-- 写入数据到大对象(假设数据为 'video_data')
SELECT lowrite(fd, 'video_data');-- 关闭大对象
SELECT lo_close(fd);
COMMIT;

在这里插入图片描述

3.1 大对象存储与TOAST的区别

  • 使用场景

    • TOAST适用于自动管理大数据的表列,如存储超长的文本或JSON数据。
    • 大对象适用于需要程序手动管理的数据块,如存储视频、音频等大型二进制文件。
  • 存取方式

    • TOAST数据存取是自动的,用户看不到TOAST表,操作透明。
    • 大对象需要应用程序显式读写,需使用PostgreSQL提供的函数进行管理。
  • 大小限制

    • TOAST处理的数据大小受限于表行的存储容量。
    • 大对象可处理更大的数据块,支持高达4TB的存储。

总结:TOAST适合无需手动管理的大数据列,而大对象适合需要精细控制和管理的超大数据存储。


4. 页面缓冲表

页面缓冲机制是PSQL性能优化的关键组件,确保数据在内存中的高效访问。页面缓冲表的结构如下:

4.1 页面缓冲机制概述

  • 缓冲区标签 (Buffer Tag):唯一标识一个页面。

    • RelFileNode:文件节点,标识特定的数据库对象。
      示例:一个数据库文件在存储系统中的唯一标识符。

    • Table space node:表空间节点。
      示例:如果我们有不同的表空间用于存储数据,Table space node将帮助区分这些空间。

    • dbNode:数据库节点。
      示例:用于标识具体的数据库,如生产数据库或测试数据库。

    • relNode:关系节点。
      示例:标识具体的表或索引。

    • forkNum:标识页面类型,如表、FSM(自由空间映射)、VM(可见性映射)。
      示例:用于区分不同的页面用途,如存储数据或索引。

    • blockNum:页面索引。
      示例:指定在文件中的具体页码。

  • 缓冲区描述符

    • Buffer TagBuffer Id:标识和定位缓冲区内的页面。
    • 多分区缓冲区锁:用于并发访问控制。
    • Reference Count:当前访问此页面的进程数。
    • Usage Count:页面被访问的次数。

4.2 描述符状态

  • Ref & usage count == 0,表示页面未被使用。
  • 未钉住Ref count == 0 && usage count > 0,页面在缓冲区中但未被锁定。
  • 钉住Ref count > 1 && usage count > 1,页面被多个进程访问且被锁定。

示例:如果一个页面在短时间内被频繁访问,其Usage Count将递增,提高其在缓冲区中的优先级,减少被淘汰的可能性。
在这里插入图片描述

4.3 页面缓冲机制的优化

为了提升页面缓冲机制的效率,可以采取以下优化措施:

  1. 调节缓冲区大小

    • 根据服务器内存和工作负载调整shared_buffers参数,以确保足够的缓冲区用于热点数据。

    示例

    shared_buffers = 4GB
    

2.监控缓冲区命中率

  • 通过监控缓冲区命中率(buffer hit rate)来评估缓冲区配置的有效性,调整参数以优化性能。

示例

SELECT sum(blks_hit) / sum(blks_read + blks_hit) AS hit_rate 
FROM pg_stat_database;

5. TOAST与大对象存储的综合应用解析

在PostgreSQL数据库中,处理大数据时常会遇到TOAST与大对象存储的选择问题。了解它们的区别与应用场景,有助于在数据库设计中做出明智的选择。

5.1 使用场景对比

  • TOAST

    • 适用于表列内自动管理的大数据,如存储超长文本、JSON、数组等。
    • 自动处理,无需用户干预,适合简单应用场景。
  • 大对象

    • 适用于需要程序手动管理的数据块,如视频、音频、图像等大型二进制文件。
    • 提供更细粒度的控制,适合需要精细数据操作的复杂应用场景。

5.2 存取方式对比

  • TOAST

    • 数据存取是透明的,用户通过常规的SQL语句操作表数据,TOAST在背后自动处理。
  • 大对象

    • 需要应用程序通过PostgreSQL提供的函数显式读写,如lo_createlo_openlowritelo_read等。

    示例

    BEGIN;
    -- 创建大对象
    SELECT lo_create(0) AS oid;-- 假设获取的oid是 12345
    -- 打开大对象
    SELECT lo_open(12345, 131072) AS fd;-- 写入数据到大对象(假设数据为 'binary_data')
    SELECT lowrite(fd, 'binary_data');-- 关闭大对象
    SELECT lo_close(fd);
    COMMIT;
    

5.3 大小限制对比

  • TOAST

    • 处理的数据大小受限于表行的存储容量,通常适用于单列数据超过2KB但不至于极大的数据。
  • 大对象

    • 支持高达4TB的存储,适合存储非常大的数据块。

5.4 选择建议

  • 如果数据的大小和访问模式适合表列自动处理,且无需精细控制,选择TOAST更为简便高效。
  • 如果需要存储和管理极大的数据块,并且需要对数据的读写进行精细控制,选择大对象更为合适。

结论

通过深入理解PSQL的内部结构和页面缓冲机制,以及掌握TOAST与大对象存储的区别与应用场景,用户可以显著提高数据库的性能和响应速度。这不仅支持更高效的应用程序开发和运行,还能在复杂的数据处理需求中提供卓越的支持。

综合优化建议

  1. 合理设计表结构和索引,确保数据存取高效。
  2. 根据数据特点选择合适的存储机制,如TOAST或大对象。
  3. 优化缓冲区配置,提升内存利用率和数据访问速度。
  4. 定期维护数据库,通过VACUUMANALYZE保持数据健康和查询优化。
  5. 监控数据库性能,通过日志和统计信息发现并解决潜在的性能瓶颈。

希望本文为您提供了有价值的见解。如有疑问或需进一步探讨,欢迎交流!

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

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

相关文章

SQL Server 可观测最佳实践

SQL Server 简介 SQL Server 是微软公司开发的一款关系数据库管理系统,支持企业 IT 环境中的各种事务处理、商业智能和分析应用程序。它支持多种操作系统平台,而无论是物理还是虚拟形式,自建部署环境还是在云环境中,运行的操作系…

MySQL8 安装配置及卸载教程

MySQL8 安装配置及卸载教程 0 卸载 MySQL 如果之前没安过 MySQL ,或者卸载干净了不用看这个。 如果安装中出现以下问题,有可能是为之前安装 MySQL 不成功,有残留的安装程序等文件程序或者是卸载 MySQL 不成功。 0.1 停止服务 首先进入服务…

大数据-194 数据挖掘 机器学习理论 有监督、无监督、半监督、强化学习

点一下关注吧!!!非常感谢!!持续更新!!! 目前已经更新到了: Hadoop(已更完)HDFS(已更完)MapReduce(已更完&am…

Java最全面试题->数据库/中间件->KafKa面试题

文章目录 KafKaKafka中的ISR、AR代表什么?ISR的伸缩指什么?kafka中的broker 是干什么的?kafka中的 zookeeper 起到什么作用?kafka follower如何与leader同步数据?kafka 为什么那么快?kafka producer如何优化打入速度?kafka producer发送数据,ack为0,1,-1分别是什么意…

兼容Lodash的真正替代者

大家好,我是农村程序员,独立开发者,前端之虎陈随易。 这是我的个人网站:https://chensuiyi.me,欢迎一起交朋友~ 今天给大家分享一个前端工具库 Lodash 的替代品 es-toolkit。 仓库地址:https://github.com…

鼠标增强工具 MousePlus v5.3.9.0 中文绿色版

MousePlus 是一款功能强大的鼠标增强工具,它可以帮助用户提高鼠标操作效率和精准度。该软件可以自定义鼠标的各种功能和行为,让用户根据自己的习惯和需求来调整鼠标的表现。 详细功能 自定义鼠标按钮功能:可以为鼠标的各个按钮设置不同的功能…

基于SpringBoot+Vue+MySQL的中药材进存销管理系统

系统展示 系统背景 中药材在医疗保健领域具有重要地位,随着中药材市场的不断发展,对中药材的进存销管理提出了更高的要求。传统的管理方式效率低下,容易出现错误和漏洞,无法满足快速发展的市场需求。因此,开发一套集成…

Nginx+Tomcat 动静分离

1. NginxTomcat 环境 Nginx 处理静态资源的优势同样可以应用在 Tomcat 环境中 。从实现方法上来说,NginxTomcat 环境的搭建思路与前面完成的 NginxApache 环境是完全相同的,只需要将 Nginx 与 Tomcat 的站点文档目录配置到同一目录下,利用 N…

npm安装过程的问题

报错信息C:\Users\lyyds>npm list -global npm error code ENOENT npm error syscall lstat npm error path D:\nodejs\node_global npm error errno -4058 npm error enoent ENOENT: no such file or directory, lstat D:\nodejs\node_global npm error enoent This is rel…

数通自学——VLAN虚拟局域网,eNSP实验讲解

VLAN虚拟局域网,eNSP实验讲解 一、概念二、eNSP仿真实验1、实验一:vlan演示(交换机端口access模式)2、实验二:vlan演示(交换机端口trunk模式) 一、概念 VLAN(Virtual Local Area Ne…

SQL-lab靶场less1-4

说明:部分内容来源于网络,如有侵权联系删除 前情提要:搭建sql-lab本地靶场的时候发现一些致命的报错: 这个程序只能在php 5.x上运行,在php 7及更高版本上,函数“mysql_query”和一些相关函数被删除&#xf…

java中的二叉树

二叉树 树型结构概念相关概念树的表示形式树的应用 二叉树概念两种特殊的二叉树二叉树的性质二叉树的存储二叉树的基本操作前置说明二叉树的遍历二叉树的基本操作 二叉树相关OJ题 树型结构 概念 树是一种非线性的的数据结构,它是由n(n>0)个有限结点组成一个具有…

贵州鑫宏远农业-始终致力于推动现代农业的科技创新与发展

贵州鑫宏远农业科技有限公司,是一家在高科技农业领域深耕细作、锐意进取的企业。自成立以来,我们始终致力于推动现代农业的科技创新与发展,业务全面覆盖农业科学研发、组织培养生产、专业育苗培植、半成品及成品精细化养护、市场销售以及全方…

对比两个el-table,差异数据突显标记

前言 在数据分析和数据处理的过程中,经常需要对比两个数据集,以便发现其中的差异和变化。本文将介绍如何使用 el-table 组件来对比两个数据集,并通过差异数据的突显标记,帮助用户更直观地理解数据的变化。 cell-style 属性 其实利…

如何用 obdiag 排查 OceanBase数据库的卡合并问题——《OceanBase诊断系列》14

1. 背景 卡合并在OceanBase中是一个复杂的问题,其产生可能源于多种因素。目前,对于卡合并的明确界定尚不存在统一标准,一方面,我们界定超过36小时未完成合并为合并超时,此时RS会记录ERROR日志;另一方面&am…

4个硬盘数据修复攻略:让你的数据失而复得。

据统计,在硬盘数据丢失的情况当中,有7成是因误删除、格式化和病毒攻击导致的。并且对与很多人来说,数据丢失是一个不小的问题。今天我就给大家分享几款能够帮助硬盘恢复数据的工具,希望能够在数据丢失是减小大家的焦虑。 1、福昕硬…

mac nwjs程序签名公证(其他mac程序也一样适用)

为什么需要公证 mac os14.5之后的系统,如果不对应用进行公证,安装,打开,权限使用上都会存在问题,而且有些问题你强制开启(sudo spctl --master-disable)使用后可能会有另外的问题, …

Python+pytest接口自动化之session会话保持的实现

前言 在接口测试的过程中,经常会遇到有些接口需要在登录的状态下才能请求,否则会提示请登录,那么怎样解决呢?我们可以通过Cookie绕过登录,其实这就是保持登录状态的方法之一。那么今天笔者想讲通过session进行会话保持…

衡石分析平台系统分析人员手册-导入图表库图表

导入图表库图表​ 本文讲述在仪表盘中如何使用图表库图表,如果您还不了解图表库,请先点击链接了解它的功能和作用。 在数据集市中建立图表库后,分析人员可以在应用创作中引用图表库图表,快速的进行数据分析工作。 导入图表库图…

Unix:Linux的“祖师爷”

目录 Unix的诞生 Unix对Linux的深远影响 Unix与Linux区别在哪里? Unix的诞生 Unix操作系统诞生于1969年,由肯汤普逊(Kenneth Lane Thompson)和丹尼斯里奇(Dennis MacAlistair Ritchie)在AT&T的贝尔实…