更新时间:2025-09-12 GMT+08:00
分享

CREATE VIEW

功能描述

创建一个视图。视图与基本表不同,是一个虚拟的表。数据库中仅存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。若基本表中的数据发生变化,从视图中查询出的数据也随之改变。从这个意义上讲,视图就像一个窗口,透过它可以看到数据库中用户感兴趣的数据及变化。

  • 将经常使用的数据定义为视图,可以将复杂的查询SQL语句进行封装。简化操作。
  • 安全性,用户只能查询视图定义的数据。隐藏基表字段,保护数据库的数据结构。
  • 简化用户权限的管理,只授予用户使用视图的权限。

注意事项

被授予CREATE ANY TABLE权限的用户,可以在public模式和用户模式下创建视图。

语法格式

CREATE [ OR REPLACE ] [ TEMPORARY ] VIEW view_name [ ( column_name [, ...] ) ]
    [ WITH ( {view_option_name [= view_option_value]} [, ... ] ) ]
    AS query
    [ WITH [ CASCADED | LOCAL ] CHECK OPTION ];

创建视图时使用WITH(security_barrier)可以创建一个相对安全的视图,避免攻击者利用低成本函数的RAISE语句打印出隐藏的基表数据。

当不开启精度传递开关(m_format_behavior_compat_options不开启enable_precision_decimal选项)时,含有以下数据类型的字段,在query中不允许进行计算操作(如函数调用、使用操作符计算),仅允许直接的字段调用(如 SELECT col1 FROM table1),精度传递开关打开(m_format_behavior_compat_options开启enable_precision_decimal选项)时可以使用:

  • BINARY[(n)]
  • VARBINARY(n)
  • CHAR[(n)]
  • VARCHAR(n)
  • TIME[(p)]
  • DATETIME[(p)]
  • TIMESTAMP[(p)]
  • BIT[(n)]
  • NUMERIC[(p[,s])]
  • DECIMAL[(p[,s])]
  • DEC[(p[,s])]
  • FIXED[(p[,s])]
  • FLOAT4[(p, s)]
  • FLOAT8[(p,s)]
  • FLOAT[(p)]
  • REAL[(p, s)]
  • FLOAT[(p, s)]
  • DOUBLE[(p,s)]
  • DOUBLE PRECISION[(p,s)]
  • TEXT
  • TINYTEXT
  • MEDIUMTEXT
  • LONGTEXT
  • BLOB
  • TINYBLOB
  • MEDIUMBLOB
  • LONGBLOB
对视图和子查询的更新、视图的插入和删除的约束涉及到的一些概念,解释如下:
  • 连接视图:多张表JOIN创建的视图。
  • 保留键表:对多表连接视图进行插入、更新、删除受到键保留表的限制。在多表视图中,若源表的每一行与视图中的每一行一一对应, 而不存在源表中一行数据在JOIN连接后在视图中对应多行数据的情况,则源表为保留键表。
  • 顶层与底层关系:视图可能有多层嵌套,如一个视图由一个或多个视图或子查询构成。将当前DML直接操作的视图称为顶层,将构成视图的表、视图、及WITH子句中的表、视图等称为对应的底层关系。
  • 可更新列:不是系统列或whole-row reference,直接引用基表中的用户列的列可更新。
  • 可更新视图:可以对视图做插入、更新、删除操作的,称为可更新视图。可更新视图不包含DISTINCT、GROUP BY、HAVING、LIMIT、OFFSET子句 ,不包含集合运算(UNION以及EXCEPT),并且不包含聚集函数、窗口函数、返回集合函数(array_agg、json_agg、generate_series等)。
  • 当视图创建后,不允许使用REPLACE修改不可更新视图当中的列名、列类型,也不允许删除列;可更新视图允许更新视图列名、列类型,允许删除列。
  • 不建议对嵌套视图中底层视图做修改列名、列类型以及删除列操作,会导致上层视图不可用。
  • 不开启精度传递开关(m_format_behavior_compat_options不开启enable_precision_decimal选项)时创建的视图,与开启精度传递开关的视图在小数位数、计算结果小数值、浮点数的比较结果等方面可能出现不一致的情况。精度开关未开启情况下创建的视图,如果在精度开关开启后使用,建议打开精度开关重建视图。

参数说明

  • OR REPLACE

    可选。如果视图已存在,则重新定义。

  • TEMPORARY

    可选。创建一个临时视图。在当前会话结束时会自动删除掉视图。如果视图引用的任何表是临时表,视图将被创建为临时视图(不管SQL中有没有指定TEMPORARY)。

  • view_name

    要创建的视图名称。可以用模式修饰。

    取值范围:字符串,符合标识符说明

  • column_name

    可选的名称列表,用作视图的字段名。如果没有给出,字段名取自查询中的字段名。

    取值范围:字符串,符合标识符说明

  • view_option_name [= view_option_value]

    该子句为视图指定一个可选的参数。

    目前view_option_name支持的参数仅有security_barrier,当VIEW试图提供行级安全时,应使用该参数。

    取值范围:Boolean类型,true、false。

  • query

    为视图提供行和列的SELECT或VALUES语句。

    若query包含指定分区表分区的子句,创建视图会将所指定分区的OID固化到系统表中。如果使用导致指定分区的OID发生变更的分区DDL语法,如DROP/SPLIT/MERGE该分区,则会导致视图不可用。需要重新创建视图。

  • WITH [ CASCADED | LOCAL ] CHECK OPTION

    控制更新视图的行为,对视图的INSERT和UPDATE,要检查确保新行满足视图定义的条件,即新行可以通过视图查询显示。如果没有通过检查,则拒绝修改。如果没有添加该选项,则允许通过对视图的INSERT和UPDATE来创建该视图不可见的行。WITH CHECK OPTION选项可以指定为CASCADED或LOCAL,语义分别如下:

    CASCADED: 检查该视图和所有底层视图定义的条件。如果仅声明了CHECK OPTION,没有声明LOCAL和CASCADED,默认是CASCADED。

    LOCAL: 只检查视图本身直接定义的条件,除非底层视图也定义了CHECK OPTION,否则底层视图定义的条件都不检查。

    • 如果指定了CHECK OPTION,无法对多表连接视图或多表连接子查询中的连接列进行插入、更新操作。
    • 如果指定了CHECK OPTION,若多表连接视图或多表连接子查询中出现重复基表,且重复的基表不都是保留键表,则无法对该视图或子查询进行删除操作。

示例

  • 普通视图:
    --创建test_tb1表,并向表中插入100条数据。
    m_db=# CREATE TABLE test_tb1(col1 int, col2 int);
    m_db=# INSERT INTO test_tb1 VALUES (generate_series(1,100),generate_series(1,100));
    --创建一个col1小于5的视图。
    m_db=# CREATE VIEW test_v1 AS SELECT * FROM test_tb1 WHERE col1 < 3;
    --查看视图。
    m_db=# SELECT * FROM test_v1;
     col1 | col2 
    ------+------
        1 |    1
        2 |    2
    (2 rows)
    
    --删除表和视图。
    m_db=# DROP VIEW test_v1;
    m_db=# DROP TABLE test_tb1;
  • 临时视图:
    --创建表和临时视图。
    m_db=# CREATE TABLE test_tb2(c1 int, c2 int);
    m_db=# CREATE TEMPORARY VIEW test_v2 AS SELECT * FROM test_tb2;
    --查看表和视图信息(临时表所属模式不是public,而是以pg_temp开头的模式)。
    m_db=# \d
                                                 List of relations
              Schema          |   Name   | Type  | Owner |                       Storage                        
    --------------------------+----------+-------+-------+------------------------------------------------------
     pg_temp_dn_6001_1_1_9473 | test_v2  | view  | omm   | 
     public                   | test_tb2 | table | omm   | {orientation=row,compression=no,storage_type=USTORE}
    (2 rows)
    
    --退出当前会话重新登录后,再次查看临时视图已经被删除。
    m_db=# \d
                                        List of relations
     Schema |   Name   | Type  | Owner |                       Storage                        
    --------+----------+-------+-------+------------------------------------------------------
     public | test_tb2 | table | omm   | {orientation=row,compression=no,storage_type=USTORE}
    (1 row)
    
    --删除视图和表。
    m_db=# DROP VIEW test_v2 ;
    m_db=# DROP TABLE test_tb2 CASCADE;

相关链接

ALTER VIEWDROP VIEW

相关文档