gzip

使用SQL执行Gzip压缩与解压缩

概览

扩展包名版本分类许可证语言
pg_gzip1.0.0UTILMITC
ID扩展名BinLibLoadCreateTrustReloc模式
4010gzip-
相关扩展bzip zstd http pg_net pg_curl pgjq pgjwt pg_smtp_client

版本

类型仓库版本PG 大版本包名依赖
EXTMIXED1.0.01817161514pg_gzip-
RPMPGDG1.0.01817161514pg_gzip_$v-
DEBPIGSTY1.0.01817161514postgresql-$v-gzip-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
d12.aarch64
d13.x86_64
d13.aarch64
u22.x86_64
u22.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
u24.x86_64
u24.aarch64
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0
PIGSTY 1.0.0

构建

您可以使用 pig build 命令构建 pg_gzip 扩展的 RPM / DEB 包:

pig build pkg pg_gzip         # 构建 RPM / DEB 包

安装

您可以直接安装 pg_gzip 扩展包的预置二进制包,首先确保 PGDGPIGSTY 仓库已经添加并启用:

pig repo add pgsql -u          # 添加仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

pig install pg_gzip;          # 当前活跃 PG 版本安装
pig ext install -y pg_gzip -v 18  # PG 18
pig ext install -y pg_gzip -v 17  # PG 17
pig ext install -y pg_gzip -v 16  # PG 16
pig ext install -y pg_gzip -v 15  # PG 15
pig ext install -y pg_gzip -v 14  # PG 14
dnf install -y pg_gzip_18       # PG 18
dnf install -y pg_gzip_17       # PG 17
dnf install -y pg_gzip_16       # PG 16
dnf install -y pg_gzip_15       # PG 15
dnf install -y pg_gzip_14       # PG 14
apt install -y postgresql-18-gzip   # PG 18
apt install -y postgresql-17-gzip   # PG 17
apt install -y postgresql-16-gzip   # PG 16
apt install -y postgresql-15-gzip   # PG 15
apt install -y postgresql-14-gzip   # PG 14

创建扩展

CREATE EXTENSION gzip;

用法

有时需要在将 bytea 对象返回给客户端之前对其进行压缩。

有时从客户端接收到压缩过的 bytea,需要先解压才能进行处理。

本扩展正是为此而设计的。

本扩展不适用于存储压缩场景。PostgreSQL 本身已经具备元组压缩机制,当元组足够大时会自动进行压缩,手动使用本函数预压缩数据并不会进一步减小存储空间。

  • gzip(uncompressed BYTEA, [compression_level INTEGER]) 返回 BYTEA
  • gzip(uncompressed TEXT, [compression_level INTEGER]) 返回 BYTEA
  • gunzip(compressed BYTEA) 返回 BYTEA

示例

> SELECT gzip('this is my this is my this is my this is my text');

                                   gzip
--------------------------------------------------------------------------
 \x1f8b08000000000000132bc9c82c5600a2dc4a851282ccd48a12002e7a22ff30000000

等等,压缩后的输出怎么反而更长了?!其实并非如此,只是看起来更长罢了,因为十六进制表示中每个字节需要两个十六进制字符。原始字符串的十六进制表示如下:

> SELECT 'this is my this is my this is my this is my text'::bytea;

                                               bytea
----------------------------------------------------------------------------------------------------
 \x74686973206973206d792074686973206973206d792074686973206973206d792074686973206973206d792074657874

对于真正较长且重复度高的内容,压缩效果自然非常显著:

> SELECT gzip(repeat('this is my ', 100));

                                               bytea
----------------------------------------------------------------------------------------------------
 \x1f8b08000000000000132bc9c82c5600a2dc4a859251e628739439ca24970900d1341c5c4c040000

要将 bytea 转换回等价的 text,必须使用 encode() 函数并指定 escape 编码方式。

> SELECT encode('test text'::bytea, 'escape');
   encode
-----------
 test text

> SELECT encode(gunzip(gzip('this text has been compressed and then decompressed')), 'escape')

                      encode
-----------------------------------------------------
 this text has been compressed and then decompressed

最后修改 2026-03-08: add extension catalog (baacba6)