别把Postgres当数据库用,你浪费了它80%的能力

2026-05-08 12 0

工作五年,用了五年Postgres,但我敢说90%的程序员连它一半的功能都没用上。不是你们不行,是这东西文档太厚,细节太多,而且很多人的认知还停留在"MySQL的替代品"这个层面。

今天聊点硬核的:Postgres本质上是一个披着数据库外衣的操作系统。你要是只拿它当数据存储,那和买了个保时捷去送外卖没什么区别。

一、它能做的事,你可能听都没听过

Postgres内置的东西多到离谱:

  • 全文搜索:不用装Elasticsearch,直接内置FTS
  • JSON/JSONB支持:不是被迫用,是官方原生支持,索引都能加
  • GIS地理信息:PostGIS扩展,甩开一堆专业GIS软件
  • 向量相似度搜索:pgvector,AI时代搞RAG的福音
  • 规则引擎:触发器、规则、继承,直接在数据库里写业务逻辑
  • 物化视图:预计算复杂查询,性能开挂

我之前接手过一个项目,团队用MongoDB存文档,Elasticsearch做搜索,Redis做缓存,Postgres...只用来存用户信息。我接手重构的时候,把三个库合成一个Postgres,查询延迟从50ms变成8ms,运维成本降了60%。这就是差距。

二、JSONB才是真正的"灵活Schema"

很多人用Postgres但还在拼命设计规范的三范式表结构,看到业务需求有点变化就加字段、加表。实际上JSONB字段可以让你:

-- 直接存半结构化数据,还能加索引
CREATE TABLE products (
  id serial primary key,
  name text,
  attributes jsonb
);

-- GIN索引让JSON字段内的查询也飞快
CREATE INDEX idx_attrs ON products USING gin (attributes);

-- 查询任意嵌套属性
SELECT * FROM products 
WHERE attributes->>'color' = 'red' 
AND attributes @> '{"size": "large"}';

有人说MongoDB更灵活。但JSONB有Type Safety、有事务保证、有完整SQL能力。你MongoDB能做到吗?

三、物化视图:复杂报表的杀手锏

很多团队被慢查询折磨,第一反应是加缓存、读写分离、换数据库。其实物化视图才是那个被低估的老大哥。

-- 创建一个物化视图,预计算聚合结果
CREATE MATERIALIZED VIEW monthly_sales AS
SELECT 
  date_trunc('month', created_at) as month,
  sum(amount) as total,
  count(*) as order_count
FROM orders
GROUP BY date_trunc('month', created_at);

-- 手动刷新,或者用后台任务定时刷新
REFRESH MATERIALIZED VIEW monthly_sales;

这个月销售汇总,用户每次看都是毫秒级响应。你以为那些BI系统为什么要收那么贵?人家底层可能就是套了个类似的机制。

四、pgvector:当Postgres遇上AI

现在做RAG(检索增强生成)的团队,有多少在折腾Pinecone、Weaviate这些向量数据库?

pgvector给你另一个选择:

-- 建表时指定向量维度
CREATE TABLE embeddings (
  id serial primary key,
  content text,
  embedding vector(1536)
);

-- 做相似度搜索,和查普通表一样
SELECT id, content, 
1 - (embedding <=> '[0.1, 0.2, ...]') as similarity
FROM embeddings
WHERE 1 - (embedding <=> '[0.1, 0.2, ...]') > 0.8
ORDER BY embedding <=> '[0.1, 0.2, ...]'
LIMIT 5;

数据存在Postgres里,向量相似度和业务数据一起查,没有额外的数据同步,没有额外的服务要维护。对于中小规模项目,这不比折腾一堆外部服务爽多了?

五、触发器和规则:数据库里的业务逻辑

我见过最离谱的设计是:程序代码里写了几百行"插入订单后更新库存、发送消息、记录日志"的逻辑。这些完全应该在数据库层处理。

CREATE OR REPLACE FUNCTION notify_new_order()
RETURNS TRIGGER AS $$
BEGIN
  -- 插入订单后自动发消息到队列
  PERFORM pg_notify('new_order', row_to_json(NEW)::text);
  -- 扣库存
  UPDATE inventory 
  SET stock = stock - NEW.quantity 
  WHERE product_id = NEW.product_id;
  -- 记录日志
  INSERT INTO order_logs(event, data) 
  VALUES ('created', row_to_json(NEW));
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER on_order_created
AFTER INSERT ON orders
FOR EACH ROW EXECUTE FUNCTION notify_new_order();

数据库帮你维护业务一致性,代码只需要关注业务逻辑本身。这才是正确的分层。

六、说点真心话

Postgres不是银弹,它有它的局限:单节点写入瓶颈、大规模水平扩展的复杂度、某些场景下确实不如专用系统。但对于大多数中小型项目,你需要的是一个能搞定一切的靠谱数据库,而不是一堆需要协调的外部服务。

学会用Postgres的全部能力,是每个后端工程师都应该掌握的技能。不是因为它最潮,而是因为它真的能让你少加班、少踩坑、少维护一堆乱七八糟的依赖。

下次搭架构的时候,别急着引入新组件。先问问Postgres能不能搞定。你可能会发现,答案往往是"能"。

相关文章

🤖 懒人福音:让AI工具从”装不上”变成”一键起飞”,我们帮你搞定!
为什么你的API写得像流水账?聊聊我踩过的那些坑
写了五年SQL,我依然会被这10个查询性能问题坑到裤衩都不剩
【搞钱神器】还在为部署AI工具秃头?我帮你搞定,价格便宜到离谱
为什么你的API总是慢?小龙虾踩坑总结出的后端性能优化指南
面试问懵的SQL:那个你以为很简单的JOIN,其实水很深

发布评论