知行札记
专题技术实践数据库实践PostgreSQL 实践

PostgreSQL 环境与实例

辨认服务器、客户端、数据库、schema 和版本条件。

本分册采用 PostgreSQL 18 文档作为语法和行为基线。归档中 PostgreSQL 16 或其他环境的 SQL、计划与耗时保留为历史记录,2026-10-05 整理未重跑这些数据库实验。示例需在独立可丢弃数据库内使用,各章同名表可能有不同结构;先核对 DDL、角色和数据再执行。

开一家简易的在线书店,先回答三个问题:图书、订单、顾客的数据放在哪里才不会乱?用什么软件来管它们?这个软件怎么装、怎么连、内部长什么样?本章就按"数据 → 软件 → 上手"的顺序一口气讲完。读完本章,你将能说清数据库与数据库管理系统的区别,理解关系模型中"表、行、列、类型"四件套,知道为什么本书选 PostgreSQL,并在自己的电脑上跑通第一条 SQL。这家在线书店是贯穿全书的构造案例——从一张 books 表开始,我们会逐章把它养成一个完整的数据库。

1.1 什么是数据库:从一张图书表说起

先看麻烦是怎么长出来的。书目记在一个电子表格里、订单记在另一个:两个人同时改库存,后保存的悄悄覆盖先保存的;同一个作者一处写成"鲁迅"、一处多敲了空格,统计时变成两个人;想查"价格低于 50 元且库存大于 10 本的书",只能一遍遍手工筛选。麻烦的根源不在表格软件不好用,而在于数据缺少一套组织纪律。

数据库(Database)就是这套纪律的载体:它是按一定结构组织、长期存储在计算机中、可被多个用户共享的数据集合。注意,这个词指的是"数据本身"。而帮我们创建、管理、维护这些数据的软件,叫数据库管理系统(Database Management System, DBMS)。PostgreSQL 属于后者:它是开源的对象关系型数据库管理系统(Object-Relational DBMS, ORDBMS),官方对它的自我介绍是"强大、开源的对象关系型数据库系统"。一个类比:数据库是账本,DBMS 是管家。但要说准确些——在 PostgreSQL 里你从不直接翻账本(数据文件),你面对的始终是管家提供的 SQL 接口。

那"按结构组织"长什么样?主流答案是关系模型(Relational Model)。PostgreSQL 官方教程有句直白的话:"Relation 本质上就是'表'的数学术语。"在关系模型里,一切围绕表(Table)展开:

  • 表是命名的行(Row)的集合,比如一张 books 表存放全部图书;
  • 每一行代表一条记录,例如某一本书;
  • 每一行都有相同的命名列(Column):title、author、stock……
  • 每一列都属于一个特定的数据类型(Data Type)。

为书店建第一张表只需一条 SQL 语句:

CREATE TABLE books (
    title     varchar(80),   -- 书名:最长 80 个字符的任意字符串
    author    varchar(80),   -- 作者
    stock     int,           -- 库存数量:普通整数
    price     real,          -- 单价:单精度浮点数
    published date           -- 出版日期
);

类型同时约束可存储的值和可用运算——数据库替你把关,写错就拒收:

INSERT INTO books (title, stock) VALUES ('测试书', 'abc');
-- ERROR:  invalid input syntax for type integer: "abc"
-- stock 列是 int 类型,'abc' 不是合法整数,整条插入被拒绝

这就是"列有类型、类型即约束":电子表格里把 abc 敲进数字列,往往只是被悄悄当成文本;数据库却当场报错。从此"库存只能是整数"这类规则有了第一道防线。

另一个必须现在就建立的认知:表中的行没有隐含顺序。官方文档明确指出,SQL 不以任何方式保证表内行的顺序。先插入三本书,再对比两条查询:

INSERT INTO books VALUES ('PostgreSQL 权威指南', '张三', 12, 98.0, '2023-06-01');
INSERT INTO books VALUES ('SQL 必知必会', '李四', 5, 49.0, '2020-04-01');
INSERT INTO books VALUES ('数据库系统概念', '王五', 20, 89.5, '2012-07-01');

SELECT * FROM books;                     -- 返回所有行,但顺序不保证
SELECT * FROM books ORDER BY price DESC; -- 按单价从高到低:顺序唯一确定

想要确定的输出顺序,唯一的办法是在 SELECT 里写 ORDER BY——这是初学者最容易忽略的一条铁律。

最后预告类型系统的另一面:除了 varchar、int、real、date 这些通用类型,PostgreSQL 还有几何类型 point(官方教程称之为"PostgreSQL 特有数据类型"),以及数组、JSON/JSONB、自定义类型等。丰富的类型库是它"对象关系型"这一定语的重要来源,后续章节会逐个用到。

1.2 为什么选择 PostgreSQL

既然 MySQL、SQL Server 也能存书,为什么本书选它?四个理由。

一是久经考验。PostgreSQL 起源于 1986 年加州大学伯克利分校的 POSTGRES 项目,核心平台至今已有近 40 年活跃开发;自 2001 年起完全符合 ACID 标准——原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability),即事务(Transaction)的四项承诺,细节留到事务一章。成熟的架构、可靠性、数据完整性与可扩展性,是官方介绍页的关键词。

二是 SQL 标准符合度高。截至 v18,PostgreSQL 支持 SQL:2023 核心标准 177 个强制特性中的至少 170 个——而目前尚无任何数据库完全符合该标准。对学习者而言,这意味着在 PostgreSQL 上学到的 SQL 最接近标准语法,将来换数据库时迁移成本最低。

三是许可证宽松、社区治理。PostgreSQL 采用 PostgreSQL License(类 BSD/MIT 的宽松许可),商业使用没有附加义务;项目由 PostgreSQL 全球开发组(PostgreSQL Global Development Group)社区驱动,没有单一厂商控制。对比之下,MySQL 采用 GPL 许可——衍生作品可能负有开源义务,除非购买商业授权——且路线图受 Oracle 一家公司影响。

四是它与最常被拿来比较的 MySQL 各有侧重:PostgreSQL 是对象关系型,MySQL 偏纯关系型;PostgreSQL 原生实现了多版本并发控制(Multiversion Concurrency Control, MVCC),MySQL 的 MVCC 依赖 InnoDB 存储引擎实现;PostgreSQL 数据类型更丰富(数组、range、JSONB、自定义类型),MySQL 则以简单、易上手著称。两者都是优秀的开源数据库——初学阶段要做的是了解差异,而不是急于站队。

1.3 版本号怎么读,支持有多久

打开任何教程都会遇到 18.6、16.15 这样的版本号,规则一句话:18.6 = 大版本 18 + 小版本 6。官方版本政策是:大约每年发布一个新的大版本(实际都落在秋季),每个大版本自发布起支持 5 年,因此任何时刻大约同时支持 5 个大版本;小版本只包含缺陷与安全修复,至少每季度发布一次。

升级成本由版本号直接决定:小版本升级只需停机、替换二进制文件、重启,不需要导出重导数据;跨大版本才需要 pg_upgrade 工具或转储/重导(dump/restore)。看懂版本号,就能预估升级的工作量。

以 2026 年 10 月的官方支持表为准,受支持的版本是 18.6、17.11、16.15、15.19、14.24;最新稳定大版本是 PostgreSQL 18(2025 年 9 月 25 日首发)。三点提醒:PostgreSQL 14 将于 2026 年 11 月 12 日停止支持,正用 14 的读者该排期升级了;PostgreSQL 13 已于 2025 年 11 月 13 日结束支持,市面不少旧书基于 12/13,跟练前先核版本;PostgreSQL 19 目前处于 Beta 阶段(Beta 4 于 2026 年 9 月 24 日发布),转正之后 18 依然在 5 年支持期内。本书以 18 为基准版本,各章示例在 14~18 全部受支持版本上均可运行。

1.4 安装方式概览:选一条最短路径

初学者常在"选哪种安装方式"上纠结,原则只有一条:先装上、能连上,就是对的。官方下载页 postgresql.org/download 按平台给出了全部入口。

macOS 有五种途径:EDB 交互式安装器(自带 pgAdmin 图形界面与 StackBuilder 附加组件安装器)、菜单栏常驻的 Postgres.app、Homebrew(brew install postgresql@18),以及 MacPorts 和 Fink。Windows 的主流选择是 EDB 交互式安装器(同样捆绑 pgAdmin),另有免安装的 zip 二进制包。Linux 官方建议优先使用发行版自带的包管理器(自动获得安全补丁、与系统集成好),需要更新版本时再添加官方 apt/yum 软件源;源码编译留给有特殊需求的读者。

想保持系统干净,Docker 是"用完即扔"示例环境的首选,一行命令起一个 PostgreSQL 18:

# -e 超级用户密码(唯一必填变量);-d 后台运行;-p 端口映射;-v 数据卷持久化
docker run --name pg-practice \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -d -p 5432:5432 \
  -v pgdata:/var/lib/postgresql \
  postgres:18

随后 psql -h localhost -U postgres 即可连入(提示输入密码时,输入的就是上面 POSTGRES_PASSWORD 设的值,本例为 mysecretpassword)。两条 Docker 跟学常用命令顺带记住:docker exec -it pg-practice bash 进入容器内部操作(本书 4.8 与 7.6 节需要修改 postgresql.conf 时由此进入,配置文件路径可用 SHOW config_file; 查询);改完配置 docker restart pg-practice 重启容器即可生效。注意一个真实的坑:18 版官方镜像把数据挂载路径从 /var/lib/postgresql/data 改成了 /var/lib/postgresql。若使用 17 及以下的镜像,数据卷必须挂旧路径,否则容器重建时数据不会持久化——网上新旧教程混杂,照抄前先核对版本。

云托管是另一条路:AWS 的 Amazon RDS for PostgreSQL 与 Aurora PostgreSQL、Microsoft Azure 的 Azure Database for PostgreSQL(Flexible Server)、Google Cloud 的 Cloud SQL for PostgreSQL 与 AlloyDB,都免去了安装、备份与高可用运维。不过初学阶段建议本地装一套:SQL 知识在云上完全通用,而本地环境随手可试、推倒重来零成本。

1.5 第一次连接:psql 入门

装好之后,认识第一个工具。官方教程列出访问数据库的三种方式:psql 命令行、图形前端(如 pgAdmin 或支持 ODBC/JDBC 的办公套件)、以及用语言绑定编写的自定义应用程序。本书以 psql 为主战场——它是随 PostgreSQL 附带的交互式终端,输入什么立刻得到什么,最适合练出手感。

第一步,创建一个数据库。psql 之外,PostgreSQL 还自带一组命令行小程序:

createdb bookshop   # 创建名为 bookshop 的数据库
dropdb  bookshop    # 删除数据库:物理删除其全部文件,不可撤销!

两条命名规则顺带记住:数据库名首字符必须是字母或下划线,长度上限 63 字节。dropdb 必须显式写库名(这是防误删的最后一道闸),且一旦执行不可撤销——请把它当作与"格式化硬盘"同级的操作。

第二步,进入 psql:

psql bookshop

提示符变为 bookshop=>:=> 表示普通用户,bookshop=# 则表示超级用户。(不写库名时,psql 默认连接与当前用户同名的数据库。)现在依次执行三条最短的 SQL——每条都以分号结尾:

SELECT version();      -- 查服务器版本号,后续示例据此核对文档版本
SELECT current_date;   -- 问服务器今天几号
SELECT 2 + 2;          -- 让数据库当一回计算器:返回 4

psql 的世界里有两套命令,务必分清:以分号结尾的是 SQL 语句;以反斜杠开头的是 psql 元命令,它们不是 SQL,不需要分号。最常用的一批:

元命令作用
\h查看 SQL 语法帮助(如 \h SELECT)
\?查看元命令自身的帮助
\d列出表、视图等对象;\d books 显示该表的列、类型与约束
\dt只列出表
\l列出服务器上的所有数据库
\du列出所有角色(用户)
\c bookshop2新建连接,改连另一个数据库
\i basics.sql执行文件里的 SQL 语句
\q退出 psql

连接远程或 Docker 里的服务器时,用参数指明目标:

psql -h localhost -p 5432 -U postgres -d bookshop  # 主机、端口、用户、数据库
psql -d bookshop -c 'SELECT version();'            # 执行一条命令即退出;-c 的字符串作为单个事务执行

psql 是客户端程序:同一台机器上它连本机服务,服务器在远程或 Docker 里时它同样能连——要紧的是分清"客户端在哪里"和"服务器在哪里"。

第三步,把 1.1 节的建表、插入与查询语句在 bookshop 库里亲手敲一遍,完成"建表 → 写入 → 查询 → 看报错"的第一个完整闭环。随时用 \d books 检查表结构,用 \q 退出。从下一章起,我们正式开始经营这家书店。

1.6 图形客户端:pgAdmin 与 DBeaver

命令行之外,图形客户端适合"看"。pgAdmin 是开源的 PostgreSQL 管理与开发平台,既能以桌面应用运行,也能以 Web 应用运行;EDB 的 Windows/macOS 安装器默认捆绑它,装完即有,当前版本为 pgAdmin 4 v9.18(2026 年 9 月 17 日发布)。DBeaver 的 Community 版免费开源(Apache-2.0 许可),开箱即支持 100 多种数据库驱动,适合同时接触多种数据库的学习者。

两者的上手路径一样:新建连接,填主机、端口、用户名、密码、数据库名,连接成功后在对象树里展开 bookshop 库,找到 books 表查看它的列与类型,再打开 SQL 编辑窗口执行一条 SELECT * FROM books;。给初学者的建议很明确:图形界面用来看结构、看数据,SQL 示例沿用 psql 的交互格式——本书后续章节默认你在 psql 里敲命令。

1.7 实例结构:从集群到表

连上服务器后,你面对的对象其实分四层。官方文档的 Schemas 一节给出层级:一个数据库集群(Database Cluster)——由单个 PostgreSQL 服务器实例管理——包含一个或多个数据库(Database);一个数据库包含一个或多个模式(Schema);表、函数、数据类型等对象放在 schema 里。

两条必须记住的规则。第一,一次客户端连接只能访问连接时指定的那一个数据库;要换库,必须新建连接(psql 里就是 \c)。从 SQL Server 或 MySQL 转来的学习者尤其要适应:PostgreSQL 里不能在一个连接中随意跨库查询。第二,schema 类似操作系统的目录(但不能嵌套):不同 schema 下可以有同名表而互不冲突——就像不同文件夹里各有一份 readme.txt。

每个新数据库默认自带一个名为 public 的 schema。不写前缀建表时,CREATE TABLE books (...) 实际等价于 CREATE TABLE public.books (...)。解析不带前缀的对象名时,PostgreSQL 按搜索路径(search_path)依次查找,默认值是 "$user", public。书店做大后,可以把不同业务的表分进各自的 schema:

SHOW search_path;                     -- 查看当前搜索路径,默认输出 "$user", public
CREATE SCHEMA catalog;                -- 为图书目录单建一个 schema
SET search_path TO catalog, public;   -- 把 catalog 排到搜索路径最前
CREATE TABLE books (id int);          -- 建到了 catalog.books,与 public.books 互不冲突

建完用 \dt 查看:输出里专门有一列 Schema,标明每张表住在哪个 schema。最后一个实用提醒:从 PostgreSQL 15 起,public schema 的 CREATE 权限不再默认对所有用户开放。多用户环境里建表若遇到 permission denied for schema public,这是权限边界起作用——请管理员授权,或者像上面那样建自己的 schema。

1.8 幕后一览:进程模型与 MVCC 预告

最后掀开幕后看一眼,后续章节的不少伏笔都藏在这里。

PostgreSQL 采用客户端/服务器(Client/Server)模型:服务器进程——程序名就叫 postgres——负责管理数据库文件、接受客户端连接、替客户端执行 SQL 操作;客户端可以是 psql、pgAdmin 或你自己写的程序,客户端与服务器可以在不同主机上通过 TCP/IP 通信。

它的进程模型有一个鲜明特点:一个连接一个进程。服务器为每个客户端连接 fork 一个新的服务进程,此后该客户端只与这个专属进程通信,不再经过原 postgres 进程;常驻的 postgres 进程只负责监听新连接。现在不必深究,但请记住这个画面——将来学习连接池(Connection Pool)时,"为什么建立连接代价高、为什么要复用连接"的答案就在这里。

再留一个预告。PostgreSQL 内部用 MVCC 维护数据一致性:每条 SQL 语句看到的都是数据在过去某一时刻的快照(Snapshot),由此为每个会话提供事务隔离;它最大的好处是"读永远不阻塞写,写永远不阻塞读"。本章记住这一句话就足够了,机制细节将在事务与并发一章展开。

常见误区

  • 忘记写分号。 SQL 语句必须以分号结尾;只按回车只是换行等待续写(提示符变成 bookshop-> 之类),不是卡死。反斜杠元命令(如 \q)不需要分号。
  • 以为表有默认顺序。 SQL 不以任何方式保证表内行的顺序,两次查询顺序不同不代表数据坏了。想要确定顺序,必须写 ORDER BY。
  • Docker 数据卷挂错路径。 PostgreSQL 18 镜像挂 /var/lib/postgresql,17 及以下必须挂 /var/lib/postgresql/data;挂错路径,容器重建时数据不会持久化。
  • 误读版本号、照抄旧教程。 18.6 是"大版本 18 + 小版本 6";9.6 是命名断档前的历史版本,远比 18 旧;基于 12/13 的教程已过支持期,跟练前先核对。
  • 混淆客户端与服务器。 本机没启动 PostgreSQL 服务就运行 psql,必然连接失败;psql 启动横幅里的版本号来自客户端自身,服务器可能是另一个版本——以 SELECT version(); 的结果为准。
  • 想在一个连接里跨库查询。 一次连接只能访问一个数据库,换库要 \c 新建连接,不能像切文件夹一样随意。
  • 在 PG15+ 上往 public 建表报权限错。 permission denied for schema public 是 15 版收紧权限后的预期行为,不是坏了;请管理员授权或建自己的 schema。
  • 低估 dropdb 的破坏力。 它会物理删除数据库的所有文件且不可撤销,psql 里的 DROP DATABASE 同样致命;删除类操作永远显式写清对象名。

参考来源

  • PostgreSQL 官方文档 §1.3 Creating a Database / §1.4 Accessing a Database(Tutorial):官方资料 / 官方资料
  • PostgreSQL 官方文档 §1.2 Architectural Fundamentals(Tutorial):官方资料
  • PostgreSQL 官方文档 §2.2 Concepts / §2.3 Creating a New Table(Tutorial):官方资料 / 官方资料
  • PostgreSQL 官方文档 §13.1 Concurrency Control: Introduction(MVCC):官方资料
  • PostgreSQL 官方文档 Schemas 节(DDL 章节):官方资料
  • PostgreSQL 官方 psql 参考页:官方资料
  • PostgreSQL 官方版本支持政策页:官方资料
  • PostgreSQL 官方下载页及各平台子页:官方资料
  • Docker Hub 官方 postgres 镜像页:官方资料
  • PostgreSQL 官方 About 页:官方资料
  • pgAdmin 官网:官方资料
  • DBeaver GitHub 仓库(dbeaver/dbeaver):官方资料
  • EDB 工程博客:PostgreSQL vs MySQL 深度对比(2024-09-23):官方资料
  • Aiven 工程博客:PostgreSQL vs MySQL:官方资料
  • Rapydo 博客:Multi-cloud 关系数据库服务综述:官方资料

最后更新于

本页目录