OpenGauss 视图零基础实战教程

openGauss 视图零基础实战教程

本教程基于 openGauss 数据库,结合配套的医院业务表,从入门到实操完整讲解视图的核心知识、操作方法与实战技巧,配套连贯业务案例与生活化解读,零基础可直接上手执行。

一、初识视图:到底什么是视图?

1.1 核心定义

  • 生活化类比:视图就像电脑里的文件快捷方式医院的定制化看板。快捷方式本身不存文件内容,只存文件的访问路径;视图本身不存储任何真实数据,数据库里只存视图的定义(一条 SELECT 查询语句),当你查询视图时,数据库会自动执行这条查询,从底层的「基本表」(真实存数据的表)中实时取出数据。

  • 官方定义:视图是 openGauss 中的虚拟表,和真实数据表一样具备命名的列和数据行,但数据全部来自于基本表的查询结果,数据库仅存储视图的定义语句,不存储视图对应的数据。

  • 核心组成:视图名 + 视图定义(SELECT 查询语句)

1.2 用视图的 3 大核心优势

  1. 简化复杂查询,告别重复代码
    业务场景:每次查询患者挂号完整信息,都要写 3 表 JOIN 的长 SQL,重复繁琐。
    解决方案:把固定的 JOIN 查询做成视图,后续只需SELECT * FROM 视图名即可拿到结果,无需重复写长 SQL。
    生活化举例:就像把常用的 Excel 公式存成模板,下次直接调用,不用重新敲写全量公式。

  2. 精细化权限控制,保障数据安全
    业务场景:医院导诊、实习生需要看医生的姓名、科室、职称,但绝对不能查看医生薪资;财务仅能看薪资统计,不能修改患者信息。
    解决方案:给不同角色创建专属视图,仅开放其需要的字段,仅授予角色视图的查询权限,不开放底层基本表的权限,从根源避免敏感数据泄露。
    生活化举例:就像银行柜员只能看到你的账户基本信息,看不到完整征信报告,银行给柜员开放的就是一个「权限受限的视图」。

  3. 屏蔽表结构变化,提升数据独立性
    业务场景:后续科室表his_dpt要新增「科室电话」「科室主任」字段,原有写好的查询语句很可能报错失效。
    解决方案:基于视图的查询不会受底层表新增字段的影响,只要视图用到的字段无变化,业务代码完全无需修改。
    生活化举例:就像你给文件换了存储文件夹,只要更新快捷方式的路径,双击仍能正常打开文件,无需关心文件的实际存储位置。

太官方了 我有点懵?!

二、视图核心管理:创建、查看、修改、删除

本章节全程使用配套的医院业务表(科室表his_dpt、医生表his_emp、挂号表his_reg、药品表his_drug),案例从简单到复杂,覆盖所有常用场景,所有 SQL 均适配 openGauss 官方语法,可直接复制执行。

命名规范:所有视图统一加v_前缀,与普通表区分,避免重名(openGauss 同库中视图名不能与表名重复)。

2.1 创建视图:CREATE VIEW 语法全解析

2.1.1 基础语法

CREATE [OR REPLACE] VIEW <视图名>[(<列名1>[,<列名2>]...)]
[WITH ENCRYPTION]
AS <SELECT查询语句>
[WITH CHECK OPTION];

2.1.2 关键参数通俗解读

参数 核心作用 生活化解释
OR REPLACE 视图已存在时直接覆盖,无需先删除再创建 等同于文件的「覆盖保存」,不用先删旧文件再存新文件
WITH ENCRYPTION 加密视图定义语句,加密后用户无法查看视图源码 给视图定义加密码锁,防止他人查看核心查询逻辑
WITH CHECK OPTION 强制通过视图增删改的数据,必须满足视图 SELECT 中的 WHERE 条件 给看板加准入规则,只能往心内科的看板里添加心内科医生,无法添加其他科室数据
自定义列名 给视图列起别名,无需与底层表列名一致 给看板列起用户易懂的名称,比如把emp_name改为「医生姓名」

2.1.3 分场景创建案例(循序渐进,贯穿全表)

案例 1:基于单表的基础视图(最简入门)

业务需求:给医院大厅做科室导览视图,仅显示科室名称和所在位置,不暴露后台科室编码等内部字段。

-- 创建视图
CREATE VIEW v_dpt_guide
AS
SELECT dpt_name 科室名称, location 所在位置
FROM his_dpt;

-- 查询视图,语法与查询普通表完全一致
SELECT * FROM v_dpt_guide;

执行结果

科室名称 所在位置
心内科 门诊楼 2 层
普外科 门诊楼 3 层
急诊科 门诊楼 1 层
儿科 门诊楼 4 层
案例 2:带条件过滤 + 权限控制的单表视图

业务需求:给心内科主任创建视图,仅能查看心内科医生信息,隐藏敏感薪资字段,同时限制只能操作心内科数据。

-- 创建视图,自定义列名,加WHERE条件与WITH CHECK OPTION
CREATE VIEW v_nei01_doctor(医生编号, 医生姓名, 职称)
AS
SELECT emp_id, emp_name, title
FROM his_emp
WHERE dpt_code = 'NEI01'
WITH CHECK OPTION;

-- 查询视图
SELECT * FROM v_nei01_doctor;

执行结果

医生编号 医生姓名 职称
1 张医生 主任
3 王医生 主治

关键说明:加了WITH CHECK OPTION后,通过该视图插入 / 修改的数据,必须满足dpt_code = 'NEI01',否则直接报错,从根源防止数据越权。

案例 3:基于多表关联的视图(最常用场景)

业务需求:给挂号处做一站式挂号详情视图,无需每次写多表 JOIN,直接查看挂号单号、患者姓名、接诊医生、所属科室、挂号费。

-- 创建多表关联视图,关联挂号表、医生表、科室表
CREATE VIEW v_reg_detail
AS
SELECT 
  a.reg_id 挂号单号,
  a.pat_name 患者姓名,
  b.emp_name 接诊医生,
  c.dpt_name 所属科室,
  a.reg_fee 挂号费
FROM his_reg a
LEFT JOIN his_emp b ON a.emp_id = b.emp_id
LEFT JOIN his_dpt c ON b.dpt_code = c.dpt_code;

-- 查询视图
SELECT * FROM v_reg_detail;

执行结果

挂号单号 患者姓名 接诊医生 所属科室 挂号费
1 患者甲 张医生 心内科 50.00
2 患者乙 张医生 心内科 50.00
3 患者丙 李医生 普外科 40.00
4 患者丁 王医生 心内科 30.00
5 患者戊 赵医生 急诊科 30.00
案例 4:基于统计 + 分组的聚合视图

业务需求:给财务科做科室挂号统计视图,自动计算每个科室的接诊人次、挂号总收入、平均挂号费。

-- 创建分组统计视图
CREATE VIEW v_dpt_reg_stat(科室名称, 接诊人次, 挂号总收入, 平均挂号费)
AS
SELECT 
  c.dpt_name,
  COUNT(a.reg_id),
  SUM(a.reg_fee),
  AVG(a.reg_fee)
FROM his_reg a
LEFT JOIN his_emp b ON a.emp_id = b.emp_id
LEFT JOIN his_dpt c ON b.dpt_code = c.dpt_code
GROUP BY c.dpt_name;

-- 查询视图
SELECT * FROM v_dpt_reg_stat;

执行结果

科室名称 接诊人次 挂号总收入 平均挂号费
心内科 3 130.00 43.333333
普外科 1 40.00 40.000000
急诊科 1 30.00 30.000000
案例 5:基于视图的视图(视图嵌套)

业务需求:在挂号详情视图v_reg_detail的基础上,给心内科创建专属挂号记录视图,无需重新写多表 JOIN,直接复用已有视图。

-- 基于已有视图创建新视图
CREATE VIEW v_nei01_reg
AS
SELECT * FROM v_reg_detail
WHERE 所属科室 = '心内科';

-- 查询视图
SELECT * FROM v_nei01_reg;

执行结果

挂号单号 患者姓名 接诊医生 所属科室 挂号费
1 患者甲 张医生 心内科 50.00
2 患者乙 张医生 心内科 50.00
4 患者丁 王医生 心内科 30.00

2.1.4 openGauss 创建视图的注意事项

  1. 权限要求:创建视图的用户必须拥有CREATE VIEW权限,同时对视图定义中 SELECT 涉及的表 / 列拥有SELECT权限;使用OR REPLACE时,还需要拥有视图的DROP权限。

  2. 存储位置:默认创建在当前连接的数据库中,若要指定数据库,可写为CREATE VIEW 数据库名\.视图名

  3. 加密视图:WITH ENCRYPTION创建的加密视图,无法通过系统表查看定义,仅高权限用户可操作,适合敏感业务场景。

2.2 查看视图:openGauss 查看已创建视图的方法

方式 1:gsql 客户端命令行查看(最快捷)

-- 查看当前库下所有视图
\dv

-- 查看视图的详细结构(包含字段、类型、依赖关系)
\d+ v_reg_detail

方式 2:通过系统表查询(通用,适配所有客户端)

-- 查看指定视图的定义
SELECT * FROM pg_views WHERE viewname = 'v_nei01_doctor';

-- 查看当前用户拥有的所有视图
SELECT * FROM pg_views WHERE schemaname = 'public';

2.3 修改视图:两种核心方式

openGauss 中修改视图主要有 2 种方式,适配不同场景:

场景 1:修改视图的查询逻辑(核心定义)

使用CREATE OR REPLACE VIEW直接覆盖原有视图,无需先删除,是最常用的修改方式。
业务需求:给v_nei01_doctor视图新增「所属科室」字段,修改原有视图。

-- 覆盖修改视图
CREATE OR REPLACE VIEW v_nei01_doctor(医生编号, 医生姓名, 职称, 所属科室)
AS
SELECT emp_id, emp_name, title, dpt_code
FROM his_emp
WHERE dpt_code = 'NEI01'
WITH CHECK OPTION;

-- 查询验证
SELECT * FROM v_nei01_doctor;

场景 2:修改视图的属性(名称、所有者、备注等)

使用ALTER VIEW语句,仅修改视图属性,不修改核心查询定义。

-- 1. 修改视图名称
ALTER VIEW v_nei01_doctor RENAME TO v_nei01_doc;

-- 2. 修改视图的所有者
ALTER VIEW v_nei01_doc OWNER TO 新用户名;

-- 3. 设置视图的备注
COMMENT ON VIEW v_nei01_doc IS '心内科医生信息视图';

2.4 删除视图:DROP VIEW 语法

视图不再使用时,可通过DROP VIEW语句删除,语法如下:

-- 基础语法
DROP VIEW [IF EXISTS] 视图名1 [, 视图名2...] [CASCADE | RESTRICT];

关键参数说明

  • IF EXISTS:视图不存在时不会报错,仅给出提示,避免脚本执行中断,推荐日常使用。

  • CASCADE:级联删除,同时删除依赖于当前视图的其他视图(比如v_nei01_reg依赖v_reg_detail,删除v_reg_detail时加CASCADE会同步删除v_nei01_reg)。

  • RESTRICT:限制删除(默认值),如果有其他视图依赖当前视图,会报错禁止删除,防止误删。

实操案例

-- 1. 安全删除单个视图(推荐)
DROP VIEW IF EXISTS v_dpt_guide;

-- 2. 批量删除多个视图
DROP VIEW IF EXISTS v_nei01_doc, v_dpt_reg_stat;

-- 3. 级联删除有依赖的视图
DROP VIEW IF EXISTS v_reg_detail CASCADE;

三、视图数据操作:通过视图增删改底层表数据

视图是虚拟表,本身不存储数据,通过视图执行INSERT/UPDATE/DELETE,最终都会作用到底层的基本表上。但并非所有视图都能执行数据操作,有严格的限制条件。

3.1 可操作视图的核心前提

只有基于单表、无聚合函数、无分组 / 去重、包含基本表所有非空约束字段的视图,才能正常执行增删改操作;多表视图、聚合视图等一般无法执行数据操作。

3.2 插入数据:通过视图 INSERT

成功案例:单表视图插入

业务需求:通过基础视图v_emp_base,新增一名医生信息。

-- 先创建可操作的单表视图,包含所有非空约束字段
CREATE VIEW v_emp_base
AS
SELECT emp_id, emp_name, dpt_code
FROM his_emp
WITH CHECK OPTION;

-- 通过视图插入数据,语法与插入普通表完全一致
INSERT INTO v_emp_base VALUES (7, '周医生', 'PED01');

-- 验证:查询底层基本表,数据已成功插入
SELECT * FROM his_emp WHERE emp_id = 7;

关键约束:WITH CHECK OPTION 的作用

如果视图有 WHERE 过滤条件,加了WITH CHECK OPTION后,插入的数据必须满足 WHERE 条件,否则会报错。

-- 尝试通过心内科视图插入儿科医生,会直接报错
INSERT INTO v_nei01_doctor(医生编号, 医生姓名, 职称, 所属科室) 
VALUES (8, '吴医生', '主治', 'PED01');

报错原因:插入的数据不满足视图定义中的dpt_code = 'NEI01'条件,WITH CHECK OPTION阻止了非法数据插入。

3.3 修改数据:通过视图 UPDATE

和插入规则一致,仅可操作单表视图,且修改后的数据必须满足WITH CHECK OPTION的约束条件。

-- 通过视图修改周医生的所属科室
UPDATE v_emp_base SET dpt_code = 'WAI01' WHERE emp_id = 7;

-- 验证修改结果
SELECT * FROM v_emp_base WHERE emp_id = 7;

3.4 删除数据:通过视图 DELETE

仅可操作基于单表、无聚合 / 分组的视图,删除的是底层基本表的数据。

-- 通过视图删除新增的周医生数据
DELETE FROM v_emp_base WHERE emp_id = 7;

-- 验证删除结果
SELECT * FROM his_emp WHERE emp_id = 7;

3.5 这些情况,视图数据操作一定会失败

  1. 基于多表关联的视图:比如v_reg_detail是 3 表 JOIN 的视图,无法执行增删改,因为数据库无法定位要修改的底层表。

  2. 不满足基本表的非空 / 主键约束:比如视图未包含基本表的主键非空字段,插入时会因主键为空报错,如同给医生建档必须填工号,否则系统无法录入。

  3. 视图定义包含聚合函数 / 数学表达式:比如统计视图v_dpt_reg_stat里有SUM/AVG,无法修改,因为这些数据是计算出来的,不是真实存储的,如同不能直接修改成绩单的平均分,只能修改每个学生的原始分数。

  4. 视图定义包含 GROUP BY/DISTINCT/UNION/HAVING:分组、去重后的视图,数据与底层单行数据不是一一对应的,无法定位要修改的具体行,因此无法操作。

四、综合动手实践:医院全角色视图落地

结合前面所有知识点,完成医院不同角色的视图落地,实现权限隔离与查询简化。

场景 1:导诊人员角色视图

  • 需求:仅能查看科室信息、医生姓名、科室、职称,无法查看薪资、挂号费等敏感数据

  • 实现 SQL:

CREATE VIEW v_guide_doc
AS
SELECT 
  b.emp_name 医生姓名,
  c.dpt_name 所属科室,
  b.title 职称,
  c.location 科室位置
FROM his_emp b
LEFT JOIN his_dpt c ON b.dpt_code = c.dpt_code;

-- 给导诊角色授予视图查询权限,不授予基本表权限
GRANT SELECT ON v_guide_doc TO guide_role;

场景 2:科室主任角色视图

  • 需求:仅能查看自己科室的医生信息、本科室的所有挂号记录

  • 实现 SQL:

-- 普外科主任视图
CREATE VIEW v_wai01_head
AS
SELECT * FROM v_reg_detail
WHERE 所属科室 = '普外科'
WITH CHECK OPTION;

-- 授予查询权限
GRANT SELECT ON v_wai01_head TO surgery_head;

场景 3:财务人员角色视图

  • 需求:查看各科室挂号收入统计、医生薪资统计,无修改权限

  • 实现 SQL:

CREATE VIEW v_finance_sal_stat(科室名称, 医生人数, 薪资总额, 平均薪资)
AS
SELECT 
  c.dpt_name,
  COUNT(b.emp_id),
  SUM(b.sal),
  AVG(b.sal)
FROM his_emp b
LEFT JOIN his_dpt c ON b.dpt_code = c.dpt_code
GROUP BY c.dpt_name;

-- 授予查询权限
GRANT SELECT ON v_finance_sal_stat TO finance_role;

五、核心总结

  1. 视图是不存储数据的虚拟表,本质是一条预定义的 SELECT 查询语句,类比为电脑的快捷方式,核心价值是简化查询、权限控制、提升数据独立性。

  2. 视图的核心管理操作:创建(CREATE VIEW)、查看(\dv/pg_views)、修改(CREATE OR REPLACE/ALTER VIEW)、删除(DROP VIEW)。

  3. 单表无聚合无分组的视图可执行增删改操作,WITH CHECK OPTION可实现数据约束,防止越权操作。

  4. 视图是数据库权限精细化管理的核心工具,企业级业务场景中,可通过视图实现不同角色的数据隔离,保障数据安全。

(注)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容