Skip to content

PostgreSQL 起步:连接、psql 与安全 SQL ​

本轮仅做正文和源码静态审阅,以下命令、SQL、集成测试及恢复流程均未执行。过去真实运行记录保留在 migration/knowledge-rebuild/m4-next/postgres/verification.md 及其原始日志;历史结果不证明修改后的示例运行通过。

版本、环境与首次连接 ​

PostgreSQL 是关系数据库:表表达一类对象,列规定值的类型,约束把可接受的数据规则放在服务端。服务进程保存数据;psql 是发送 SQL 的客户端,关闭 psql 不等于停止服务。一个实例管理多个数据库,每个数据库中可以有多个 schema(模式);本课在 postgres_lab 数据库的 public 模式操作。

前置是能在终端切换到仓库根目录,具备 Docker Desktop(Linux 容器模式)或 Linux Docker Engine、Compose 插件和 Python 3.12+。以下是供读者在自行授权的隔离环境操作的步骤,本轮审计不执行安装和启动。命令中 / 是路径分隔,PowerShell 也能接受;代码围栏标明 Shell。先执行 docker version,确认服务端可用,不能只看客户端版本。

历史交付记录于 2026-10-17 核对官方支持表,选择仍受支持的 PostgreSQL 18.6;不把 RC 当稳定版。历史服务实测为 Debian 13 x86_64 容器,Windows 运行 Python 3.12.14 客户端,另一轮在 Linux Python 容器运行同一源码。不是 Windows 原生数据库部署。macOS 不纳入本轮;生产复制、主备、PITR 和容量测试另行学习。

全部配置如下。固定 digest 保证本课镜像可追溯,示例密码只用于本机独立实验库;不将端口发布到公网。18 镜像的卷挂载点为 /var/lib/postgresql,不要照搬旧镜像的数据目录。

yaml
services:
  postgres:
    image: postgres:18.6@sha256:74935e72241653ca55e0414067e6d8763aceb8a810eb51b452253ec3dcfc4336
    container_name: showdocs-m4b-postgres-main
    environment:
      POSTGRES_USER: lab
      POSTGRES_PASSWORD: m4-local-lab
      POSTGRES_DB: postgres_lab
    ports:
      - "127.0.0.1:25432:5432"
    volumes:
      - data:/var/lib/postgresql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U lab -d postgres_lab"]
      interval: 2s
      timeout: 2s
      retries: 20
volumes:
  data:
    name: showdocs-m4b-postgres-data

PowerShell 或 Bash 在仓库根目录执行:

sh
docker compose -p showdocs-m4b-postgres -f examples/postgres/compose.yaml up -d --wait
docker exec -it showdocs-m4b-postgres-main psql -U lab -d postgres_lab

若已使用同名 docker run 实例,就复用该实例,不能再用 Compose 重建覆盖。预期进入 postgres_lab=#。连接远端或用原生客户端时写明目标并交互输入密码:psql -h 127.0.0.1 -p 25432 -U lab -d postgres_lab -W;容器内命令经本地 socket,因此不能用它证明主机端口密码认证。历史 Python 实测连接本机 25432,覆盖了主机 TCP 路径。

psql、SQL 与会话 ​

psql 的 \conninfo 显示当前连接,\dt public.* 列表,\d+ public.products 查看列、约束与索引,\q 退出。反斜线元命令由 psql 处理,不是应用驱动能执行的 SQL。SQL 用分号结束;提示符变成 postgres_lab-# 通常表示语句未结束,可用 Ctrl+C 取消输入。SQL 字符串用单引号,双引号引用区分大小写的标识符,平时优先小写不加引号的表名。

sql
SELECT current_database(), current_user, version();
SHOW server_encoding;
SELECT 1 + 2 AS total, '中文📚' AS label;

预期数据库为 postgres_lab,编码 UTF8,total 为 3。服务器和客户端编码都要正确;终端乱码不等于数据损坏。Python 项目使用 UTF-8 源码和 JSON 输出,测试把中文及 emoji 写入再读回逐值比较。

第一次读写与回滚 ​

先按应用初始化与验证安装依赖并执行到 verify 和 list,暂不执行最后一条 reserve;已做过预留或测试时,只重新执行 verify 重置两张实验表。此时 book 库存3、pen库存0,不能直接沿用上一次会话数据。首次只需照初始化步骤准备数据,事务机制在后续课程展开。SELECT 返回行集,WHERE 筛选,ORDER BY 才定义顺序。下面事务修改后回滚,便于比较会话内外的结果。

sql
SELECT sku, name, stock FROM products ORDER BY sku;
BEGIN;
UPDATE products SET stock=stock+1 WHERE sku='book' RETURNING sku,stock;
SELECT stock FROM products WHERE sku='book';
ROLLBACK;
SELECT stock FROM products WHERE sku='book';

事务内 book 为4,回滚后为3。没有 WHERE 的 UPDATE 会更新所有行,先在事务内 SELECT 检查目标再修改。psql 默认自动提交,BEGIN 到 COMMIT 才是一组事务。遇到约束错误后,事务进入失败状态,后续 SQL 会报 current transaction is aborted,需要 ROLLBACK 或回滚到预先创建的 SAVEPOINT;不要不断重复原 SQL。

脚本批量执行使用 psql -v ON_ERROR_STOP=1 -f file.sql,SQL 错误要让执行流程停止。本课验证器用异常和非零退出传递失败,不把“连接成功”当业务成功。

小练习 ​

在 verify 基线(book=3)上,在事务内把 book 增加2,观察 RETURNING,再回滚。提示:分别记录 UPDATE 返回值和 ROLLBACK 后 SELECT 值,不要在两次观察中再次运行 verify。解释为什么终端关闭后不能依赖自动回滚“撤销”已经自动提交的 UPDATE。完成后进入建模,参考解答在复习。

更多平台客户端安装路径见官方软件下载,本课可直接复用容器内 psql,不依赖未验证的 Windows 安装器。命令语义参考psql 手册。

继续阅读