CREATE VIEW 是 PostgreSQL 14 中创建视图的唯一标准方式,必须包含 CREATE VIEW 关键字、唯一视图名和 AS 后可独立执行的 SELECT 查询,不支持 ORDER BY、窗口函数、FOR UPDATE、LIMIT、OFFSET 及外部参数,且查询须满足可更新条件才能支持 INSERT/UPDATE/DELETE。

CREATE VIEW 是 PostgreSQL 14 中创建 SQL 视图的唯一标准方式,不支持 CREATE MATERIALIZED VIEW 以外的“物化”变体,也不允许在视图定义中使用 ORDER BY 或窗口函数直接参与可更新逻辑。
用 CREATE VIEW 定义基础视图
PostgreSQL 14 要求视图必须基于一个合法的 SELECT 查询,且该查询不能包含 FOR UPDATE、LIMIT、OFFSET 或外部参数(如 $1)。常见错误是误把带 ORDER BY 的查询直接塞进视图——它语法上能通过,但实际被忽略,后续查询结果顺序不可靠。
-
CREATE VIEW后面不能跟模式限定名(如public.myview)除非你明确指定 schema,否则默认建在当前search_path首个 schema 下 - 列名若未显式声明(如
SELECT a+b AS sum),会沿用表达式推导名;但若含歧义(如两个表都有id),必须用别名,否则报错column reference "id" is ambiguous - 视图不校验底层表是否存在——直到首次查询才触发
relation does not exist错误
创建可更新视图的硬性条件
PostgreSQL 14 允许通过视图执行 INSERT/UPDATE/DELETE,但前提是视图满足“简单可更新”规则:只能引用单个基表、不能有聚合、不能有 GROUP BY、不能有 DISTINCT、不能有集合操作(UNION 等)、所有列必须直接映射到基表列(不能是表达式或常量)。
PostgreSQL 18.4 官方 Ubuntu 安装包现已发布,这是目前最新的稳定版本。推荐通过官方 APT 仓库安装:先执行 sudo apt update 更新索引,再运行 sudo apt install postgresql-18 即可完成部署。新版本引入了异步 I/O 子系统,在顺序扫描与 VACUUM 场景下性能提升显著,同时支持 UUID v7 原生生成函数与虚拟生成列。
- 例如
CREATE VIEW active_users AS SELECT id, name, email FROM users WHERE status = 'active'可更新;但加个UPPER(name)就立刻失效 - 即使满足条件,也需确保
WHERE子句中的列有索引,否则UPDATE可能全表扫描——这不是语法限制,而是性能陷阱 - 尝试修改不可更新视图时,错误信息是
cannot update a view without an unconditional ON UPDATE DO INSTEAD rule,不是语法报错,容易误判为权限问题
CREATE OR REPLACE VIEW 的兼容性细节
替换已有视图时,PostgreSQL 14 要求新旧视图的输出列在数量、名称、类型、顺序上完全一致——仅允许在末尾追加新列。如果试图删掉一列或重排顺序,会报错 cannot replace view because column count differs。
- 列类型宽松匹配:比如原列是
integer,新定义为bigint不行,但smallint→integer可以(隐式转换存在) - 列名变更必须同步改所有引用它的应用代码,因为
CREATE OR REPLACE不会警告列名变化 - 依赖此视图的其他视图、函数或物化视图不会自动刷新,需手动
REFRESH MATERIALIZED VIEW或重建
临时视图与安全屏障选项
用 TEMPORARY 创建的视图只在当前会话可见,退出即销毁,适合调试复杂查询逻辑。而 security_barrier = true 选项用于强制行级安全(RLS)生效——若视图封装了带策略的表,不设此选项可能导致绕过策略。
-
CREATE TEMP VIEW tmp_summary AS SELECT ...中的TEMP关键字不可省略,否则建的是永久视图 -
WITH (security_barrier = true)必须写在AS前,位置错了会报syntax error at or near "WITH" - 递归视图(
RECURSIVE)在 PostgreSQL 14 中要求显式声明列名列表,漏写会提示recursive view must have column names
SELECT,嵌套三层视图可能让原本毫秒级的查询变成秒级。上线前务必用 EXPLAIN (ANALYZE, BUFFERS) 对视图查询做真实压测。

















