Oracle 视图

简介: 可以把Oracle视图看作是给一段复杂查询存的“快捷方式”,让你能像查一张简单的表一样去访问它,省去了每次都写长串代码的麻烦。普通视图只是个逻辑窗口,本身不存数据,主要用来简化操作和控制权限。但如果某个查询实在太慢,想用空间换时间,那就得用“物化视图”。它会真实地存一份数据副本,专门给查询提-速,是性能优化的一大杀手锏。

Oracle 视图是一个存储在数据库中命名查询,它本身不包含任何物理数据 (物化视图除外)。你可以把它看作一张“虚拟表”或一个“逻辑窗口”,通过它,用户可以以预设的方式查看一个或多个基表中的数据。

思维导图

image.png

image.png

image.png

image.png

一、视图的创建与核心选项

1.1 完整创建语法
sql CREATE [OR REPLACE] [FORCE|NOFORCE] VIEW view_name [(alias1, alias2, ...)] AS SELECT_statement [WITH CHECK OPTION [CONSTRAINT constraint_name]] [WITH READ ONLY [CONSTRAINT constraint_name]];
下面我们将逐一解析每个选项。

1.2 OR REPLACE 选项
此选项允许你 修改一个已存在的视图,而 无需先删除它。
代码案例:
sql -- 第一次创建视图 CREATE VIEW employee_v AS SELECT emp_id, emp_name FROM employees; -- 修改视图,增加 salary 列 CREATE OR REPLACE VIEW employee_v AS SELECT emp_id, emp_name, salary FROM employees;

1.3 FORCE | NOFORCE 选项
FORCE 可以在 基表不存在的情况下 强制创建视图。该视图会处于 无效(INVALID)状态。 NOFORCE 是默认行为。
代码案例:
sql -- 即使 'non_existent_table' 不存在,也强制创建视图 CREATE FORCE VIEW future_view AS SELECT col1 FROM non_existent_table; -- 查询视图状态,会看到 STATUS 为 INVALID SELECT object_name, status FROM user_objects WHERE object_name = 'FUTURE_VIEW';

1.4 列别名 [(alias1, alias2, ...)]
用于为视图的 列指定名称,当 SELECT 语句中包含 表达式或函数特别有用
代码案例:
sql CREATE OR REPLACE VIEW employee_payroll_v (employee_id, employee_name, annual_salary) AS SELECT emp_id, emp_name, salary * 12 -- 表达式需要别名 FROM employees;

1.5 WITH CHECK OPTION 选项
确保通过视图进行的DML操作 产生的新行必须 满足视图定义WHERE 子句的条件。
代码案例:
sql CREATE OR REPLACE VIEW dept_20_employees_v AS SELECT emp_id, emp_name, department_id FROM employees WHERE department_id = 20 WITH CHECK OPTION; -- 尝试将部门为20的员工更新到部门30,会失败 UPDATE dept_20_employees_v SET department_id = 30 WHERE emp_id = 201; -- ORA-01402: view WITH CHECK OPTION where-clause violation

1.6 WITH READ ONLY 选项
使视图 变为只读禁止通过它进行任何DML操作 ( INSERT, UPDATE, DELETE)。
代码案例:
sql CREATE OR REPLACE VIEW all_employees_readonly_v AS SELECT * FROM employees WITH READ ONLY; -- 尝试通过此视图删除数据,会失败 DELETE FROM all_employees_readonly_v WHERE emp_id = 101; -- ORA-42399: cannot perform a DML operation on a read-only view

## 二、视图的分类与应用 2.1 简单视图
基于单个表,不含 GROUP BY, DISTINCT, 连接, 聚合/窗口函数等。通常 可进行DML操作
代码案例:
sql -- 创建一个简单的、只显示HR部门员工的视图 CREATE OR REPLACE VIEW hr_employees_v AS SELECT emp_id, emp_name, salary FROM employees WHERE department_id = 30; -- 通过简单视图更新数据 UPDATE hr_employees_v SET salary = salary + 1000 WHERE emp_id = 301; COMMIT;

2.2 复杂视图
包含 连接、聚合、函数等复杂逻辑。通常 只读
代码案例:
sql -- 创建一个显示各部门员工总数的复杂视图 CREATE OR REPLACE VIEW dept_employee_count_v (department_name, employee_count) AS SELECT d.department_name, COUNT(e.emp_id) FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY d.department_name; -- 查询复杂视图 SELECT * FROM dept_employee_count_v;

2.3 内联视图
定义在查询的 FROM 子句中的 临时子查询,用完即弃。
代码案例:
sql -- 使用内联视图找出每个部门薪水最高的人 SELECT department_name, emp_name, salary FROM ( SELECT d.department_name, e.emp_name, e.salary, ROW_NUMBER() OVER(PARTITION BY e.department_id ORDER BY e.salary DESC) AS rn FROM employees e JOIN departments d ON e.department_id = d.department_id ) -- 这是内联视图 WHERE rn = 1;

## 三、物化视图

与普通视图不同,物化视图存储查询结果的物理副本,以空间换时间,用于加速复杂查询的性能。

3.1 创建物化视图
语法要点: REFRESH [FAST|COMPLETE|FORCE] ON [COMMIT|DEMAND], BUILD [IMMEDIATE|DEFERRED], ENABLE QUERY REWRITE
代码案例:
sql -- 为快速刷新创建物化视图日志 CREATE MATERIALIZED VIEW LOG ON employees WITH ROWID; CREATE MATERIALIZED VIEW LOG ON departments WITH ROWID; -- 创建一个可快速刷新的、按需刷新的物化视图 CREATE MATERIALIZED VIEW dept_summary_mv BUILD IMMEDIATE REFRESH FAST ON DEMAND ENABLE QUERY REWRITE AS SELECT d.department_name, COUNT(e.emp_id) AS emp_count, SUM(e.salary) AS total_sal FROM employees e JOIN departments d ON e.department_id = d.department_id GROUP BY d.department_name;

3.2 刷新物化视图
对于 ON DEMAND 的物化视图,需要 手动刷新
代码案例:
sql -- 手动刷新 (F=FAST, C=COMPLETE, ?=FORCE) EXEC DBMS_MVIEW.REFRESH('DEPT_SUMMARY_MV', 'C');

## 四、视图的管理 4.1 查询视图定义
使用 数据字典 USER_VIEWSALL_VIEWS
代码案例:
sql SELECT view_name, text FROM user_views WHERE view_name LIKE 'DEPT%';

4.2 删除视图
DROP VIEW 用于普通视图, DROP MATERIALIZED VIEW 用于物化视图。
代码案例:
sql DROP VIEW hr_employees_v; DROP MATERIALIZED VIEW dept_summary_mv;

总结:
简单/复杂视图核心是逻辑抽象,不存数据。 内联视图查询内部的临时工作台,非常灵活。
物化视图性能优化的大杀器,核心挑战是数据同步策略

---

## *练习题

背景表结构:

CREATE TABLE products (
    product_id     NUMBER PRIMARY KEY,
    product_name   VARCHAR2(100),
    category       VARCHAR2(50),
    price          NUMBER(8, 2),
    stock_quantity NUMBER
);
CREATE TABLE sales (
    sale_id       NUMBER PRIMARY KEY,
    product_id    NUMBER,
    customer_id   NUMBER,
    sale_date     DATE,
    quantity_sold NUMBER
);

请为以下每个场景编写相应的SQL语句。

题目:

  1. 创建一个名为 electronics_products_v 的简单视图,显示 products 表中所有 category 为 'Electronics' 的产品信息 (所有列)。
  2. 创建一个名为 product_sales_summary_v 的复杂视图,显示每个产品 (product_name) 的总销售数量 (total_quantity) 和总销售额 (total_revenue,即 price * quantity_sold 的总和)。
  3. 通过 electronics_products_v 视图,将 product_id 为 (假设一个电子产品ID) 101 的产品的 stock_quantity 更新为 50。
  4. 创建一个只读视图 readonly_products_v,包含 products 表的所有信息。
  5. 创建一个视图 low_stock_alerts_v,显示 stock_quantity 小于10的产品信息,并确保通过此视图更新产品时,stock_quantity 仍然必须小于10。
  6. 使用内联视图,查询出每个产品类别中,价格第二高的产品的名称和价格。
  7. 创建一个物化视图 monthly_category_sales_mv,按需完全刷新,用于存储每个产品类别每月的总销售额。
  8. 写出手动刷新 monthly_category_sales_mv 的命令。
  9. 查询数据字典,找出当前用户下所有视图的名称和其定义SQL文本。
  10. 删除视图 electronics_products_v 和物化视图 monthly_category_sales_mv
答案与解析:
  1. 创建简单视图 electronics_products_v:

    CREATE OR REPLACE VIEW electronics_products_v AS
    SELECT product_id, product_name, category, price, stock_quantity
    FROM products
    WHERE category = 'Electronics';
    
    • 解析: 这是一个基于单表、无聚合/连接的简单视图,可以用于DML操作。
  2. 创建复杂视图 product_sales_summary_v:

    CREATE OR REPLACE VIEW product_sales_summary_v AS
    SELECT
    p.product_name,
    SUM(s.quantity_sold) AS total_quantity,
    SUM(p.price * s.quantity_sold) AS total_revenue
    FROM products p
    JOIN sales s ON p.product_id = s.product_id
    GROUP BY p.product_name;
    
    • 解析: 包含了连接和聚合函数,是一个典型的只读复杂视图。
  3. 通过视图更新数据:

    UPDATE electronics_products_v
    SET stock_quantity = 50
    WHERE product_id = 101;
    COMMIT;
    
    • 解析: 由于 electronics_products_v 是一个简单视图,可以通过它直接更新基表 products 的数据。
  4. 创建只读视图:

    CREATE OR REPLACE VIEW readonly_products_v AS
    SELECT * FROM products
    WITH READ ONLY;
    
    • 解析: WITH READ ONLY 关键字确保了此视图不能被用于 INSERT, UPDATE, DELETE 操作。
  5. 创建带检查选项的视图:

    CREATE OR REPLACE VIEW low_stock_alerts_v AS
    SELECT * FROM products
    WHERE stock_quantity < 10
    WITH CHECK OPTION;
    
    • 解析: WITH CHECK OPTION 意味着,如果你尝试 UPDATE low_stock_alerts_v SET stock_quantity = 15 WHERE ...,该操作会失败,因为新值15不满足 stock_quantity < 10 的条件。
  6. 使用内联视图查询价格第二高的产品:

    SELECT product_name, price, category
    FROM (
    SELECT
    product_name, price, category,
    DENSE_RANK() OVER (PARTITION BY category ORDER BY price DESC) as rnk
    FROM products
    )
    WHERE rnk = 2;
    
    • 解析: 内联视图先计算出每个类别内的价格排名,外层查询再筛选出排名为2的记录。
  7. 创建物化视图 monthly_category_sales_mv:

    CREATE MATERIALIZED VIEW monthly_category_sales_mv
    BUILD IMMEDIATE
    REFRESH COMPLETE ON DEMAND
    AS
    SELECT
    p.category,
    TO_CHAR(s.sale_date, 'YYYY-MM') AS sale_month,
    SUM(p.price * s.quantity_sold) AS monthly_revenue
    FROM products p
    JOIN sales s ON p.product_id = s.product_id
    GROUP BY p.category, TO_CHAR(s.sale_date, 'YYYY-MM');
    
    • 解析: 创建了一个存储物理数据的物化视图,用于快速查询每月各品类的销售额。
  8. 手动刷新物化视图:

    EXEC DBMS_MVIEW.REFRESH('MONTHLY_CATEGORY_SALES_MV');
    
    • 解析: DBMS_MVIEW.REFRESH 是刷新物化视图的标准包程序。默认刷新方式是FORCE
  9. 查询数据字典:

    SELECT view_name, text FROM user_views;
    
    • 解析: user_views 是一个数据字典视图,存储了当前用户拥有的所有视图的定义信息。
  10. 删除视图:

    DROP VIEW electronics_products_v;
    DROP MATERIALIZED VIEW monthly_category_sales_mv;
    
    • 解析: 删除普通视图使用 DROP VIEW,删除物化视图使用 DROP MATERIALIZED VIEW
目录
相关文章
|
8天前
|
云安全 监控 安全
|
13天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1425 8
|
7天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
469 11
|
19天前
|
人工智能 Java API
Java 正式进入 Agentic AI 时代:Spring AI Alibaba 1.1 发布背后的技术演进
Spring AI Alibaba 1.1 正式发布,提供极简方式构建企业级AI智能体。基于ReactAgent核心,支持多智能体协作、上下文工程与生产级管控,助力开发者快速打造可靠、可扩展的智能应用。
1255 43
|
19天前
|
人工智能 前端开发 算法
大厂CIO独家分享:AI如何重塑开发者未来十年
在 AI 时代,若你还在紧盯代码量、执着于全栈工程师的招聘,或者仅凭技术贡献率来评判价值,执着于业务提效的比例而忽略产研价值,你很可能已经被所谓的“常识”困住了脚步。
1160 88
大厂CIO独家分享:AI如何重塑开发者未来十年
|
1天前
|
存储 弹性计算 容灾
阿里云服务器ECS自定义购买流程:超详细新手入门教程
本文详细介绍阿里云服务器ECS自定义购买全流程,涵盖付费模式、地域选择、网络配置、实例规格、镜像系统、存储、公网IP、带宽计费及安全组设置等关键步骤,适合新手入门参考,助你轻松完成云服务器选购与部署。
194 121