最佳 Postgres 插件(2023 版)

可扩展性在 Postgres 的基因里,这要归功于其原始设计

file

这种设计理念赋予了 Postgres 许多独特的能力,其中之一就是它的插件。通过 Postgres 插件,第三方可以在不触碰任何 Postgres 核心代码的情况下扩展其功能。

如今,大多跑在生产环境中的 Postgres 都运行着一些插件,以下我们介绍一些最常用的。

file

pg_stat_statements

pg_stat_statements 提供了跟踪服务器执行的所有 SQL 语句的规划和执行统计信息的方法。当 pg_stat_statements 处于活动状态时,它会跟踪服务器上所有数据库的统计信息。该模块收集到的统计数据可以通过一个名为 pg_stat_statements 的视图进行访问。

不过要注意,pg_stat_statements 插件仅跟踪自启用后执行的查询。如果想要跟踪所有查询,请在服务器启动时将以下行添加到 postgresql.conf 文件中来启用该插件:

shared_preload_libraries = 'pg_stat_statements'

比如要找到总执行时间最长的前 10 个查询:

SELECT query, total_time
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 10;

PostGIS

PostGIS 为 Postgres 添加了对地理数据的存储、索引和查询支持,它是最复杂的 Postgres 插件,也从侧面证明了 Postgres 的扩展系统有多强大。

比如要找到离给定点最近的城市:

  1. 假设我们有以下包含城市及其位置(用坐标表示)的表。注:location 列具有由 PostGIS 插件提供的 GEOMETRY 类型。
CREATE TABLE cities (
name TEXT,
location GEOMETRY(Point, 4326)
);
  1. 要找到离给定点最近的地方,可以用 ST_Distance 函数来计算该点与表中每个地方之间的距离,然后按照距离对结果进行排序。例如,以下命令可找到离纽约(-74.005941, 40.712784)最近的城市:
SELECT name, ST_Distance(location, ST_SetSRID(ST_MakePoint(-74.005941, 40.712784), 4326)) AS distance
FROM cities
ORDER BY location <-> ST_SetSRID(ST_MakePoint(-74.005941, 40.712784), 4326)
LIMIT 1;

这个查询计算了 cities 表中每个城市与坐标 (-74.005941, 40.712784) 之间的距离,并使用 <-> 对结果进行排序,LIMIT 1 子句返回最近的城市。

不过注意,ST_Distance 函数默认以米为单位返回两点之间的距离。你可以通过使用适当的 PostGIS 函数(例如 ST_Distance_Sphere)将结果转换为其他测量单位,比如千米。

postgres_fdw

postgres_fdw 可以用于访问存储在外部 Postgres 服务器中的数据,它是 dblink 插件的继任者,但提供了更透明和符合标准的语法来访问远程表,并且在许多情况下可以提供更好的性能。

使用 postgres_fdw,你可以查询任何其他 Postgres 数据库。

  1. 创建一个用来查询的新数据库。例如,我们这里创建一个名为 my_other_database 的库:
    CREATE DATABASE my_other_database;
  2. 连接到要创建外部表的数据库(这里,我们将使用默认的 postgres 数据库)。
  3. 为将访问远程数据库的用户创建用户映射。例如,如果想使用当前连接的相同用户,可以运行以下命令:
CREATE USER MAPPING FOR current_user
SERVER my_other_database
OPTIONS (user 'postgres', password '');
  1. 使用 postgres_fdw 插件创建一个外部服务器。
CREATE SERVER my_other_database_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (dbname 'my_other_database');

这个命令使用 postgres_fdw 外部数据封装器创建了一个名为 my_other_database_server 的服务器,并将 dbname 选项设置为 my_other_database。
5. 在本地数据库中创建一个外部表,将其映射到远程的 my_other_database 数据库中的一张表。

CREATE FOREIGN TABLE my_other_table (
id INTEGER,
name TEXT
)
SERVER my_other_database_server
OPTIONS (schema_name 'public', table_name 'my_table');

这个命令在本地数据库中创建了一个名为 my_other_table 的外部表,它映射到 my_other_database 数据库的 public schema 下的一个名为 my_table 的表。
6. 可以像使用普通表一样,在查询中使用这个外部表。
SELECT * FROM my_other_table WHERE id = 1;
你还可以在查询中将外部表与本地表连接,就像处理常规表一样。
注意,在使用 postgres_fdw 查询同一 Postgres 实例上的远程数据库时,你可能需要调整 postgresql.conf 文件并重新启动 Postgres 服务器,以便让其他数据库能够访问 pg_hba.conf 文件。

uuid-ossp

uuid-ossp 提供了使用几种标准算法之一生成通用唯一标识符 (UUID) 的函数。Postgres 已经内置了 gen_random_uuid() 函数来生成 v4 UUID (随机)。如果想生成其他版本的 UUID,需要使用 uuid-ossp。

比如,生成 v5 UUID:
SELECT uuid_generate_v5(uuid_ns_url(), 'example.com');
这个命令基于 URL 的命名空间标识符 (uuid_ns_url()) 和名称字符串 ‘example.com’ 生成了一个 v5 UUID。输出类似:f1f5d9f0-2a4c-5f24-9536-3f1f69e68a7e

你还可以使用 uuid-ossp 函数 uuid_ns_create() 来创建自己的命名空间标识符。
SELECT uuid_ns_create('example');
此命令使用名称 ‘example’ 创建一个命名空间标识符,并将其作为 UUID 返回。
然后可以使用此命名空间标识符和名称字符串与 uuid_generate_v5() 一起生成基于该命名空间的 UUID。
在安全性比较关键的应用程序中推荐使用 UUID v5,因为它使用命名空间标识符和名称字符串的 SHA-1 哈希生成,比其他 UUID 版本更不容易发生冲突。

pg_cron

pg_cron 是一个简单的基于 cron 的任务调度程序,作为插件运行在数据库内部。它使用与常规 cron 相同的语法,但可以直接从数据库中调度 Postgres 命令。

file

  1. 创建一个新 cron 任务,运行以下命令:
    SELECT cron.schedule('0 0 * * ', 'INSERT INTO my_table SELECT FROM my_other_table');
  2. 确认任务已经创建
    SELECT cron.jobid, cron.expr, cron.command FROM cron.job;
  3. 查看正在运行和最近完成的任务状态
    select * from cron.job_run_details order by start_time desc limit 5;

timescaledb

timescaledb 提供了对时序数据的优化存储和查询功能。

  1. 创建一个 hypertable

Hypertable 是 TimescaleDB 中专门用于存储和查询时序数据的特殊类型表。可以使用 CREATE_HYPERTABLE 函数来创建 hypertable。

CREATE TABLE sensor_data (
time TIMESTAMP NOT NULL,
value FLOAT NOT NULL
);
SELECT create_hypertable('sensor_data', 'time');
  1. 插入一些数据到 sensor_data 表
INSERT INTO sensor_data (time, value)
VALUES
('2023-07-01 00:00:00', 10.0),
('2023-07-01 01:00:00', 15.0),
('2023-07-01 02:00:00', 20.0);
  1. 查询数据
    TimescaleDB 提供了许多针对时序数据进行优化的函数,例如 time_bucket 用于将数据聚合到时间间隔中。要计算每小时数据的平均值,可以运行以下查询:
SELECT time_bucket('1 hour', time) AS hour, AVG(value) AS avg_value
FROM sensor_data
GROUP BY hour;

pgvector

pgvector 提供了对向量处理的支持。你可以在数据组上执行向量化操作,这可以为特定类型的查询提供显著的性能改进。
欲获取最接近向量的邻居:

  1. 创建一个带有向量列的新表
    CREATE TABLE items (id bigserial PRIMARY KEY, embedding vector(3));
  2. 插入向量
    INSERT INTO items (embedding) VALUES ('[1,2,3]'), ('[4,5,6]');
  3. 查询向量的最近邻
    SELECT * FROM items ORDER BY embedding <-> '[3,1,2]' LIMIT 5;

🐘 Neon 最近发布了一个类似的插件 pgembedding,声称比 pgvector 快 20 倍。

总结一下

Postgres 的众多插件是与其友商 MySQL 的关键区别:比如你有业务需要处理地理空间数据,那么 Postgres 是唯一的选择(因为有 PostGIS 插件)。完整 Postgres 和 MySQL 对比请参阅「全方位对比 Postgres 和 MySQL (2023 版)」。


💡 你可以访问官网,免费注册云账号,立即体验 Bytebase。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值