gzip
使用SQL执行Gzip压缩与解压缩
仓库
pramsey/pgsql-gzip
https://github.com/pramsey/pgsql-gzip
源码
pgsql-gzip-1.0.0.tar.gz
pgsql-gzip-1.0.0.tar.gz
概览
| 扩展包名 | 版本 | 分类 | 许可证 | 语言 |
|---|---|---|---|---|
pg_gzip | 1.0.0 | UTIL | MIT | C |
| ID | 扩展名 | Bin | Lib | Load | Create | Trust | Reloc | 模式 |
|---|---|---|---|---|---|---|---|---|
| 4010 | gzip | 否 | 是 | 否 | 是 | 否 | 是 | - |
| 相关扩展 | bzip zstd http pg_net pg_curl pgjq pgjwt pg_smtp_client |
|---|
版本
| 类型 | 仓库 | 版本 | PG 大版本 | 包名 | 依赖 |
|---|---|---|---|---|---|
| EXT | MIXED | 1.0.0 | 1817161514 | pg_gzip | - |
| RPM | PGDG | 1.0.0 | 1817161514 | pg_gzip_$v | - |
| DEB | PIGSTY | 1.0.0 | 1817161514 | postgresql-$v-gzip | - |
构建
您可以使用 pig build 命令构建 pg_gzip 扩展的 RPM / DEB 包:
pig build pkg pg_gzip # 构建 RPM / DEB 包
安装
您可以直接安装 pg_gzip 扩展包的预置二进制包,首先确保 PGDG 和 PIGSTY 仓库已经添加并启用:
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])返回BYTEAgzip(uncompressed TEXT, [compression_level INTEGER])返回BYTEAgunzip(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