什么是 Postgres?许多应用背后的数据库详解
Postgres(正式名称为 PostgreSQL)是一款免费的开源关系型数据库:一个以行和列的表格形式存储应用数据、把这些表格相互关联,并使用名为 SQL 的语言回答关于它们的问题的程序。它以可靠、对数据正确性要求严格,以及足够灵活而著称,能够胜任从一份报名名单到大公司记录的各种场景。许多 Web 应用以及托管这些应用的许多服务都建立在它之上。
用 AI 构建时为什么它很重要
当 AI 应用构建器为你的项目添加“一个数据库”时,很可能用的就是 Postgres。使用它并不需要你会写 SQL,但了解一点基础知识会大有帮助:
- 你可以用数据库所需的结构来描述数据。 “客户拥有多个订单;每个订单包含多个商品”可以直接转换为数据表。
- 你可以要求正确的保护措施。 如果 AI 设置了规则,Postgres 就能自行拒绝错误的数据,例如重复的邮箱,或为不存在的客户下单。
- 你可以检查 AI 做了什么。 表名、列和关系都很容易在表格查看器中核对,即使你从不接触代码。
一个日常类比:一间非常严格的档案室
想象一间档案室,每类事物都有一个档案柜:一个放客户,一个放订单,一个放商品。每个抽屉里的卡片都印有相同的表格框要填写。每张卡片都有唯一的编号,订单卡片不会重复客户的详细信息,而只写“客户 #214”,指向客户抽屉。
这位管理员很严格。如果订单指向一个不存在的客户,他不会归档;如果某个必填的日期框是空的,他也不会接受这张卡片。而且,如果你要求把钱从一张账户卡转到另一张,他要么两边都做,要么两边都不做——绝不会只做一半。
这位管理员就是 Postgres。抽屉是表,表格框是列,每张卡片是一行,而“客户 #214”这种链接就是外键。
Postgres 擅长什么
| 功能 | 通俗含义 |
|---|---|
| 表与关系 | 数据存放在相互指向的表中,因此不会在五个地方重复复制 |
| SQL | 一种标准语言,用于提出问题:“上个月所有未付款的订单,最新的排在前面” |
| 事务(ACID) | 一组修改要么全部发生,要么全部不发生,即使服务器在中途崩溃 |
| 约束 | 数据库自身强制执行的规则:必填字段、唯一的邮箱、表之间有效的链接 |
| 索引 | 随着表格增长仍能保持搜索速度的查找捷径 |
| JSONB | 当固定结构不适用时,在一列中存储灵活的文档式数据 |
| 全文搜索 | 在简单场景下无需单独的搜索服务,即可搜索文本字段中的词语 |
| 扩展 | 附加组件,例如用于地图和位置的 PostGIS,或用于存储 AI 向量嵌入的 pgvector |
| 行级安全 | 数据库内部的规则,决定某个用户可以看到哪些行 |
Postgres 起源于 20 世纪 80 年代加州大学伯克利分校的一个研究项目,自 20 世纪 90 年代起便由全球社区公开开发。这段悠久的历史正是它常常成为默认选择的原因:文档完善、支持广泛,而且每个主要云服务商都提供其托管版本。
实例:把电子表格变成数据表
假设你经营一家小型餐饮承办公司,所有信息都记录在一份电子表格中:每一行是一场活动,包括客户的姓名、电话和邮箱、日期、菜单项目以及价格。
问题很快就会出现。同一位客户出现在六行中,而且有两个不同的电话号码。菜单项目被输入到同一个单元格中,写成“小点心 x40,沙拉 x2”,因此你无法统计本月做了多少份小点心。
在 Postgres 中,同样的信息会变成四张表:
| 表 | 列 | 说明 |
|---|---|---|
| clients(客户) | id、name、phone、email | 邮箱必须唯一 |
| events(活动) | id、client_id、date、venue、status | client_id 必须对应一个真实的客户 |
| menu_items(菜单项目) | id、name、unit_price | 每道菜一行 |
| event_items(活动项目) | event_id、menu_item_id、quantity | 把活动与菜品关联起来,并记录数量 |
现在,客户的电话号码只存在于一个地方。“三月我们做了多少份小点心?”只需一条 SQL 查询。当你记录一场新活动及其项目时,事务会确保你不会得到一个只保存了一半项目的活动。
当人们要求 AI“把我的电子表格做成应用”时,往往会跳过这一步。把电子表格变成应用的指南会进一步讲解。
关键术语
- 表、行、列: 一类事物、该类事物的一个实例、关于它的一项信息。
- 主键: 每一行的唯一 ID,通常是
id。 - 外键: 指向另一张表中某一行的列,例如
client_id。 - 模式(Schema): 所有表和列的设计。
- 迁移(Migration): 对模式的一次保存下来、可重复执行的修改,例如“在 events 中添加一个
venue列”。 - 查询(Query): 用 SQL 编写的问题或指令。
- 连接字符串: 你的后端访问数据库所用的地址和密码。它属于机密信息,参见环境变量与密钥。
- 托管的 Postgres: 由服务商为你运行、备份和更新 Postgres 的服务。
关于应用对这些表执行的日常操作——创建、读取、更新、删除——参见什么是 CRUD。
常见错误与误解
- 一张巨大的表。 把电子表格的每一列都照搬过来,会导致同样的重复问题。把会重复出现的内容拆分到各自的表中。
- 把列表存在一个文本字段里。 在单个列中写入“小点心 x40,沙拉 x2”,无法被正确统计或搜索。请使用关联表。
- 没有约束。 如果没有“邮箱必须唯一”或“每场活动都需要一个客户”之类的规则,错误数据会悄悄进入,并在数月后才显现出来。
- 在生产环境中手动修改数据库。 请把模式变更作为迁移来提出,使变更有记录且可以重复执行。
- 让浏览器直接访问数据库。 前端应通过你的后端访问,由后端检查权限。数据库密码绝不应出现在页面代码中。
- “Postgres 只适用于大公司。” 它同样能很好地支撑一个只有 50 行的候补名单,而且随着业务增长,你也无需迁移离开它。
- 以为数据库就是备份。 数据库用于存储数据,它并不会自动保护你免于误删。请确认你的主机提供了哪些备份。
向 AI 构建器提出的请求
- “把[事物]保存在数据库中。数据表:……,包含以下字段:……。把每个[订单]关联到一个[客户]。”
- “客户的邮箱设为唯一。将这些字段设为必填。不允许没有客户的订单。”
- “每一次模式变更都使用迁移。”
- “为我们最常做的搜索添加索引:按客户和按日期查询订单。”
- “所有数据库访问都通过服务器进行。把连接字符串保存在环境变量中。”
如果你对数据库这个概念还很陌生,可以先阅读什么是数据库,然后再回到这里。全栈应用一文展示了数据库与前端、后端之间的位置关系。
Mythex 中的 Postgres
Mythex 为每个需要数据库的项目提供其专属的 Postgres 数据库。你无需进行任何配置:在聊天中提出需求(例如“把候补名单邮箱保存到数据库”),或使用 /database 命令,Mythex 就会将其挂载,把连接信息注入你的应用,并且可以替你创建数据表。已发布应用的数据库在五分钟无人使用后会进入休眠,并在下一次请求时唤醒;你只需为其实际处于唤醒状态的时间付费,费用与构建时使用的是同一个积分余额。详情参见数据库文档,而仪表盘模板是查看由数据驱动的应用的好去处。
常见问题
Postgres 和 PostgreSQL 是同一个东西吗?
是的。PostgreSQL 是官方名称,Postgres 是常用的简称;两者指的都是同一个开源关系型数据库。
Postgres 免费吗?
免费。PostgreSQL 采用宽松的 PostgreSQL 许可证开源,因此你可以免费使用它,包括用于商业产品。你只需为运行它的服务器或托管服务付费。
Postgres 和 MySQL 有什么区别?
两者都是免费的关系型 SQL 数据库,对大多数应用来说都够用。Postgres 以严格的数据完整性、丰富的数据类型(例如 JSONB 和数组)以及庞大的扩展生态而闻名;MySQL 则以简单易用和在网站托管领域的长期历史著称。
Postgres 适合小型应用吗?
适合。它既能胜任单表的候补名单,也能支撑大型生产系统,因此随着应用成长,你不需要更换数据库。托管服务让你无需数据库管理员也能轻松运行它。