用途:为 PostgreSQL 设计专用的数据库表结构(schema),涵盖最佳实践、数据类型、索引、约束、性能模式与高级特性。
核心规则:为引用表(如用户、订单)定义主键,时序/事件/日志类数据不一定需要;优先使用 BIGINT GENERATED ALWAYS AS IDENTITY,仅在需要全局唯一或不透明 ID 时用 UUID。先规范到 3NF 消除冗余,仅在实测读性能确有问题时才反规范化。语义需要处加 NOT NULL,常用值设 DEFAULT。为实际查询的访问路径建索引:主键/唯一自动、外键列需手动、频繁过滤排序与连接键。事件时间用 TIMESTAMPTZ,金额用 NUMERIC,字符串用 TEXT,整数用 BIGINT,浮点用 DOUBLE PRECISION。
主要能力与注意点:PostgreSQL 标识符不加引号会小写,建议 snake_case;UNIQUE 允许多个 NULL,PG15+ 可用 NULLS NOT DISTINCT 限制;外键列不会自动建索引,需手动添加;不会静默截断,超长/超精度直接报错;序列 ID 有间隙属正常;堆存储默认不按主键聚簇,CLUSTER 只是一次性重整;MVCC 下更新删除会留死元组。
数据类型:BIGINT GENERATED ALWAYS AS IDENTITY 为首选;UUID 用 uuidv7()(PG18+)或 gen_random_uuid()。字符串用 TEXT,需长度限制用 CHECK (LENGTH(col) <= n)。金额用 NUMERIC;时间用 TIMESTAMPTZ、DATE、INTERVAL。小且稳定的集合用 ENUM,业务驱动的变化值用 TEXT + CHECK 或查找表。数组用 TEXT[] 等,GIN 索引支持包含/重叠查询。范围类型(daterange、tstzrange)用 GiST 索引。全文检索用 TSVECTOR/TSQUERY 并必须指定语言,用 GIN 索引。域名类型、复合类型、JSONB(优先于 JSON)、pgvector 向量类型按需选用。不应使用 timestamp、char(n)/varchar(n)、money、timetz、serial 等。
约束与索引:CHECK 中 NULL 会通过(三值逻辑),需配合 NOT NULL;EXCLUDE 约束可防重叠。B-tree 用于等值/范围,复合索引最左前缀,覆盖索引用 INCLUDE,部分索引用于热子集,表达式索引需在 WHERE 中精确匹配,GIN 用于 JSONB/数组/全文,GiST 用于范围/几何/排除约束,BRIN 用于超大且自然有序数据。
分区:针对超大表按 RANGE/LIST/HASH 分区,需含分区键于主键/唯一约束,分区表不支持外键。
特殊考量:更新密集表分离冷热列、用 fillfactor=90、避免更新索引列;写入密集表最小化索引、用 COPY 或多行插入、可先删索引再重建;Upsert 需目标列有唯一索引,可用 EXCLUDED 引用拟插入值;安全演进可用事务性 DDL 与 CREATE INDEX CONCURRENTLY(不能在事务中),注意易变默认值会重写全表。
生成列:GENERATED ALWAYS AS (<expr>) STORED 可索引,PG18+ 支持 VIRTUAL。常用扩展包括 pgcrypto、pg_trgm、citext、btree_gin/btree_gist、hstore、timescaledb、postgis、pgvector、pgaudit。JSONB 建议用 GIN 索引,含大量 @> 查询可用 jsonb_path_ops,但会失去键存在查询支持。