把你的数据库想象成你的家。你的家有客厅、卧室、浴室、厨房和车库。每个房间都有不同的用途。但它们都在同一个屋檐下,通过走廊和门连接。你不会仅仅因为需要做饭就建一个单独的餐厅。你也不会在城镇的另一边建造一个商业车库来停车。
这就是 Postgres。 一个有很多房间的家。搜索、向量、时间序列、队列——所有都在一个屋檐下。
但这正是专用数据库供应商不希望你听到的。他们的营销团队已经花了多年时间说服你“使用合适的工具来做合适的工作”。听起来很有道理。听起来很明智。并且可以卖出很多数据库。
让我向你展示为什么这是一个陷阱,以及为什么 Postgres 在 99% 的情况下是更好的选择。
你听过这样的建议:“使用合适的工具来做合适的工作。”
听起来很明智。所以你最终会有:
恭喜你,现在你有七个数据库需要管理。七种查询语言需要学习。七种备份策略需要维护。七种安全模型需要审计。六套凭据需要轮换。七个监控仪表盘需要观察。并且七件事情可能在凌晨 3 点坏掉。
当某件事情坏掉时?祝你好运,尝试启动一个测试环境来调试它。
这里有一个不同的想法:直接使用 Postgres。
这不仅仅是关于简单。AI 代理使数据库扩散成为噩梦。
想想代理需要做什么:
使用一个数据库?这只是一个命令。分叉、测试、完成。
使用七个数据库?现在你需要:
这几乎是不可能的,没有大量的研发。
而且不仅仅是代理。每当凌晨 3 点出现问题时,你需要启动一个测试环境来调试。有六个数据库,这是一个协调噩梦。有一个数据库,这只是一个命令。
在 AI 时代,简单不仅仅是优雅的,它是必不可少的。
让我们直接解决这个问题。
神话: 专用数据库在其特定任务中远远优于其他数据库。
现实: 有时它们在狭窄的任务中略微更好。但它们也带来了不必要的复杂性。这就像为每顿饭聘请一位私人厨师。听起来很豪华,但它增加了费用、协调开销,并制造了你以前没有的问题。
事情是这样的:99% 的公司不需要它们。前 1% 的公司有数千万用户和一支庞大的工程团队来匹配。你们读过他们关于如何使用专用数据库 X 的博客文章。但那是他们的规模,他们的团队,他们的问题。对于其他人来说,Postgres 足够了。
以下是大多数人没有意识到的事情:Postgres 扩展使用与专用数据库相同或更好的算法(在许多情况下)。
“专用数据库”的溢价?主要是营销。
| 需要什么 | 专用工具 | Postgres 扩展 | 使用相同算法? |
|---|---|---|---|
| 全文搜索 | Elasticsearch | pg_textsearch | ✅ 都使用 BM25 |
| 向量搜索 | Pinecone | pgvector + pgvectorscale | ✅ 都使用 HNSW/DiskANN |
| 时间序列 | InfluxDB | TimescaleDB | ✅ 都使用时间分区 |
| 缓存 | Redis | UNLOGGED 表 | ✅ 都使用内存存储 |
| 文档 | MongoDB | JSONB | ✅ 都使用文档索引 |
| 地理空间 | 专用 GIS | PostGIS | ✅ 自 2001 年以来就是行业标准 |
这些不是水化版本。它们是 相同/更好的算法,经过战斗测试,开源,并且通常由相同的研究人员开发。
基准测试支持这一点:
除了 AI/代理问题外,数据库扩散还有累积成本:
| 任务 | 一个数据库 | 七个数据库 |
|---|---|---|
| 备份策略 | 1 | 7 |
| 监控仪表盘 | 1 | 7 |
| 安全补丁 | 1 | 7 |
| 值班运行手册 | 1 | 7 |
| 故障转移测试 | 1 | 7 |
认知负荷: 你的团队需要 SQL、Redis 命令、Elasticsearch 查询 DSL、MongoDB 聚合、Kafka 模式和 InfluxDB 的非本地 SQL 工作区。这不是专业化。这是 碎片化。
数据一致性: 将 Elasticsearch 与 Postgres 同步?你构建同步作业。它们会失败。数据会漂移。你添加调解。它也会失败。现在你正在维护基础设施,而不是构建功能。
SLA 数学: 三个系统,每个系统的正常运行时间为 99.9% = 99.7% 的组合正常运行时间。这意味着 每年有 26 小时的停机时间,而不是 8.7 小时。每个系统都会将你的故障模式乘以。
这些扩展并不是新东西。它们已经生产就绪多年了:
超过 48,000 家公司使用 PostgreSQL,包括 Netflix、Spotify、Uber、Reddit、Instagram 和 Discord。
AI 时代带来了新一代扩展:
| 扩展 | 替代 | 亮点 |
|---|---|---|
| pgvectorscale | Pinecone、Qdrant | DiskANN 算法。与 Pinecone 相比,延迟降低了 28 倍,成本降低了 75%。 |
| pg_textsearch | Elasticsearch | Postgres 中的原生 BM25 排名。 |
| pgai | 外部 AI 流水线 | 自动同步嵌入,数据更改时触发。 |
这意味着什么: 构建一个 RAG 应用程序曾经需要 Postgres + Pinecone + Elasticsearch + 粘合代码。
现在?直接使用 Postgres。 一个数据库。一个查询语言。一个备份。一个用于 AI 代理启动测试环境的 fork 命令。
以下是你需要的所有内容:
-- 启用全文搜索与 BM25
CREATE EXTENSION pg_textsearch ;
-- 启用向量搜索用于 AI
CREATE EXTENSION vector ;
CREATE EXTENSION vectorscale ;
-- 启用 AI 嵌入和 RAG 工作流
CREATE EXTENSION ai ;
-- 启用时间序列
CREATE EXTENSION timescaledb ;
-- 启用消息队列
CREATE EXTENSION pgmq ;
-- 启用定时任务
CREATE EXTENSION pg_cron ;
-- 启用地理空间
CREATE EXTENSION postgis ;
以下是每种用例的工作示例。跳转到你需要的部分。
扩展: pg_textsearch(真实的 BM25 排名)
你正在替代:
你得到:
-- 创建表
CREATE TABLE articles (
id SERIAL PRIMARY KEY,
title TEXT,
content TEXT
);
-- 创建 BM25 索引
CREATE INDEX idx_articles_bm25 ON articles USING bm25 (content)
WITH (text_config = 'english');
-- 使用 BM25 得分搜索
SELECT title, - (content <@> '数据库优化') as score
FROM articles
ORDER BY content <@> '数据库优化'
LIMIT 10;
SELECT
title,
- (content <@> '数据库优化') as bm25_score,
embedding <=> query_embedding as vector_distance,
0.7 * (- (content <@> '数据库优化')) +
0.3 * (1 - (embedding <=> query_embedding)) as hybrid_score
FROM articles
ORDER BY hybrid_score DESC
LIMIT 10;
这就是 Elasticsearch 需要单独插件的功能。在 Postgres 中,这只是 SQL。
扩展: pgvector + pgvectorscale
你正在替代:
你得到:
-- 启用扩展
CREATE EXTENSION vector;
CREATE EXTENSION vectorscale CASCADE;
-- 带有嵌入的表
CREATE TABLE documents (
id SERIAL PRIMARY KEY,
content TEXT,
embedding vector(1536)
);
-- 高性能索引(DiskANN)
CREATE INDEX idx_docs_embedding ON documents USING diskann (embedding);
-- 查找相似文档
SELECT content, embedding <=> '[0.1, 0.2, ...]'::vector as distance
FROM documents
ORDER BY embedding <=> '[0.1, 0.2, ...]'::vector
LIMIT 10;
使用 pgai 自动同步嵌入:
SELECT ai.create_vectorizer(
'documents'::regclass,
loading => ai.loading_column(column_name => 'content'),
embedding => ai.embedding_openai(model => 'text-embedding-3-small', dimensions => '1536')
);
现在,每次插入/更新都会自动重新生成嵌入。没有同步作业。没有漂移。没有凌晨 3 点的页面。
扩展: TimescaleDB(21K+ GitHub 星标)
你正在替代:
你得到:
-- 启用 TimescaleDB
CREATE EXTENSION timescaledb;
-- 创建表
CREATE TABLE metrics (
time TIMESTAMPTZ NOT NULL,
device_id TEXT,
temperature DOUBLE PRECISION
);
-- 转换为超表
SELECT create_hypertable('metrics', 'time');
-- 使用时间桶查询
SELECT time_bucket('1 hour', time) as hour,
AVG(temperature)
FROM metrics
WHERE time > NOW() - INTERVAL '24 hours'
GROUP BY hour;
-- 自动删除旧数据
SELECT add_retention_policy('metrics', INTERVAL '30 days');
-- 压缩(90% 存储减少)
ALTER TABLE metrics SET (timescaledb.compress);
SELECT add_compression_policy('metrics', INTERVAL '7 days');
功能: UNLOGGED 表 + JSONB
-- UNLOGGED = 无 WAL 开销,写入更快
CREATE UNLOGGED TABLE cache (
key TEXT PRIMARY KEY,
value JSONB,
expires_at TIMESTAMPTZ
);
-- 设置带有过期时间
INSERT INTO cache (key, value, expires_at)
VALUES ('user:123', '{"name": "Alice"}', NOW() + INTERVAL '1 hour')
ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value;
-- 获取
SELECT value FROM cache WHERE key = 'user:123' AND expires_at > NOW();
-- 清理(使用 pg_cron 安排)
DELETE FROM cache WHERE expires_at < NOW();
扩展: pgmq
CREATE EXTENSION pgmq;
SELECT pgmq.create('my_queue');
-- 发送
SELECT pgmq.send('my_queue', '{"event": "signup", "user_id": 123}');
-- 接收(带有可见性超时)
SELECT * FROM pgmq.read('my_queue', 30, 5);
-- 删除处理后
SELECT pgmq.delete('my_queue', msg_id);
或本机 SKIP LOCKED 模式:
CREATE TABLE jobs (
id SERIAL PRIMARY KEY,
payload JSONB,
status TEXT DEFAULT 'pending'
);
-- 工作人员原子性地声明作业
UPDATE jobs SET status = 'processing'
WHERE id = (
SELECT id FROM jobs WHERE status = 'pending'
FOR UPDATE SKIP LOCKED LIMIT 1
) RETURNING *;
功能: 本机 JSONB
CREATE TABLE users (
id SERIAL PRIMARY KEY,
data JSONB
);
-- 插入嵌套文档
INSERT INTO users (data) VALUES ('{
"name": "Alice",
"profile": {"bio": "开发人员", "links": ["github.com/alice"]}
}');
-- 查询嵌套字段
SELECT data->>'name', data->'profile'->>'bio'
FROM users
WHERE data->'profile'->>'bio' LIKE '%开发人员%';
-- 索引 JSON 字段
CREATE INDEX idx_users_email ON users ((data->>'email'));
扩展: PostGIS
CREATE EXTENSION postgis;
CREATE TABLE stores (
id SERIAL PRIMARY KEY,
name TEXT,
location GEOGRAPHY(POINT, 4326)
);
-- 查找 5 公里内的商店
SELECT name, ST_Distance(location, ST_MakePoint(-122.4, 37.78)::geography) as meters
FROM stores
WHERE ST_DWithin(location, ST_MakePoint(-122.4, 37.78)::geography, 5000);
扩展: pg_cron
CREATE EXTENSION pg_cron;
-- 每小时运行一次
SELECT cron.schedule('cleanup', '0 * * * *',
$$ DELETE FROM cache WHERE expires_at < NOW() $$);
-- 每晚运行一次
SELECT cron.schedule('rollup', '0 2 * * *',
$$REFRESH MATERIALIZED VIEW CONCURRENTLY daily_stats$$);
对于 AI 应用程序,你通常需要 同时 使用关键字搜索和语义搜索:
-- 反向排名融合:合并关键字 + 语义搜索
WITH bm25 AS (
SELECT id, ROW_NUMBER() OVER (ORDER BY content <@> $1) as rank
FROM documents LIMIT 20
),
vectors AS (
SELECT id, ROW_NUMBER() OVER (ORDER BY embedding <=> $2) as rank
FROM documents LIMIT 20
)
SELECT d.*,
1.0 / (60 + COALESCE(b.rank, 1000)) +
1.0 / (60 + COALESCE(v.rank, 1000)) as score
FROM documents d
LEFT JOIN bm25 b ON d.id = b.id
LEFT JOIN vectors v ON d.id = v.id
WHERE b.id IS NOT NULL OR v.id IS NOT NULL
ORDER BY score DESC LIMIT 10;
尝试使用 Elasticsearch + Pinecone 来做到这一点。你需要两个 API 调用、结果合并、故障处理和双重延迟。
在 Postgres 中:一个查询,一个事务,一个结果。
扩展: pg_trgm(内置于 Postgres)
CREATE EXTENSION pg_trgm;
CREATE INDEX idx_name_trgm ON products USING GIN (name gin_trgm_ops);
-- 即使有拼写错误也能找到“PostgreSQL”
SELECT name FROM products
WHERE name % 'posgresql'
ORDER BY similarity(name, 'posgresql') DESC;
功能: 递归 CTE
-- 查找所有报告给经理的员工(组织图)
WITH RECURSIVE org_tree AS (
SELECT id, name, manager_id, 1 as depth
FROM employees WHERE id = 42
UNION ALL
SELECT e.id, e.name, e.manager_id, t.depth + 1
FROM employees e
JOIN org_tree t ON e.manager_id = t.id
WHERE t.depth < 10
)
SELECT * FROM org_tree;
记住家园的比喻吗?你不会仅仅因为需要做饭就建一个单独的餐厅。你不会在城镇的另一边建造一个商业车库来停车。
这就是我们在这里展示的内容。搜索、向量、时间序列、文档、队列、缓存——所有这些都是 Postgres 家中的房间。与专用数据库相同的算法。经过多年的战斗测试。由 Netflix、Uber、Discord 和 48,000 多家其他公司使用。
那么,99% 的情况呢?
对于 99% 的公司,Postgres 处理所有你需要的功能。1% 的情况?那是当你在数百个节点上处理数百万条日志,或者你需要 Kibana 的特定仪表盘,或者你有真正超过 Postgres 能力的奇异需求时。
但事情是这样的:你会知道自己是否处于 1% 中。 你不会需要供应商的营销团队告诉你。你会自己进行基准测试,并遇到真正的墙壁。
在那之前,不要因为有人告诉你“使用合适的工具来做合适的工作”而将数据分散在七栋建筑中。那些建议卖出了很多数据库,但它不为你服务。
从 Postgres 开始。继续使用 Postgres。仅在你有真正的理由需要时添加复杂性。
2026 年了,就用 Postgres 吧。
所有这些扩展都可在 Tiger Data 上使用。创建一个免费数据库,仅需几分钟:
psql "postgresql://user:[email protected]:5432/tsdb"
CREATE EXTENSION pg_textsearch; -- BM25 搜索
CREATE EXTENSION vector; -- 向量搜索
不需要专用数据库,只需使用 Postgres 即可。