每行是一个会议室,已有预订显示为彩色块。下方填写「申请」时段并提交,系统会模拟 PG 的 EXCLUDE USING gist (room WITH =, period WITH &&) 约束,冲突会被拒绝。
btree_gist 索引查找
「同 room 且 period && 新 period」的已有行;只要找到一个,就抛 exclusion_violation。
O(log N) 的索引查询足以支撑高并发预订场景。pg_cron 周期性触发 REFRESH MATERIALIZED VIEW CONCURRENTLYOVERRIDING SYSTEM VALUE 显式标注意图,比直接 INSERT 安全得多。| 约束 | 含义 | 典型 SQL |
|---|---|---|
| NOT NULL | 列不能为空 | name text NOT NULL |
| PRIMARY KEY | NOT NULL + UNIQUE,且每表唯一 | id bigint PRIMARY KEY |
| UNIQUE | 列值唯一 (NULL 默认互不冲突) | email text UNIQUE |
| FOREIGN KEY | 引用必须存在 | customer_id REFERENCES customers(id) ON DELETE CASCADE |
| CHECK | 任意确定性表达式 | CHECK (price > 0) |
| EXCLUDE | PG 独有!关系性排他 | EXCLUDE USING gist (room WITH =, period WITH &&) |
| 维度 | VIEW | MATERIALIZED VIEW |
|---|---|---|
| 数据存在哪 | 不存(只存 SQL 定义) | 真实落到磁盘 |
| 查询性能 | 每次跑底层 SQL | 查表速度 + 可加索引 |
| 数据新鲜度 | 永远实时 | 取决于上次 REFRESH |
| 可索引? | 否 | 是 |
| 可写入? | 满足条件可更新 | 否 |
| 刷新 | 无需 | REFRESH MATERIALIZED VIEW [CONCURRENTLY] |
| 维度 | SERIAL | IDENTITY (PG 10+ 推荐) |
|---|---|---|
| SQL 标准 | ❌ PG 特有 | ✅ SQL:2003 |
| 语法 | id serial PRIMARY KEY | id bigint GENERATED ALWAYS AS IDENTITY |
| 手工塞 id | 总是允许 (易踩坑) | ALWAYS 拒绝;BY DEFAULT 允许 |
| 权限 | 序列单独 GRANT | 跟随列权限 |
| 类型修改 | 繁琐 | SQL 标准 ALTER 干净 |