【Oracle】视图

news2025/6/5 23:48:37

在这里插入图片描述

个人主页:Guiat
归属专栏:Oracle

在这里插入图片描述

文章目录

  • 1. 视图基础概述
    • 1.1 视图的概念与特点
    • 1.2 视图的工作原理
    • 1.3 视图的分类
  • 2. 简单视图
    • 2.1 创建简单视图
      • 2.1.1 基本简单视图
      • 2.1.2 带计算列的简单视图
    • 2.2 简单视图的DML操作
      • 2.2.1 通过视图进行INSERT操作
      • 2.2.2 通过视图进行UPDATE操作
      • 2.2.3 通过视图进行DELETE操作
  • 3. 复杂视图
    • 3.1 多表连接视图
      • 3.1.1 员工部门视图
      • 3.1.2 员工层级关系视图
    • 3.2 聚合统计视图
      • 3.2.1 部门统计视图
      • 3.2.2 职位薪资分析视图
    • 3.3 时间序列分析视图
      • 3.3.1 年度招聘趋势视图
  • 4. 视图的更新控制
    • 4.1 WITH CHECK OPTION
      • 4.1.1 基本CHECK OPTION
      • 4.1.2 分级CHECK OPTION
    • 4.2 WITH READ ONLY
  • 5. 物化视图
    • 5.1 基本物化视图
      • 5.1.1 创建物化视图
      • 5.1.2 自动刷新物化视图
    • 5.2 快速刷新物化视图
      • 5.2.1 创建物化视图日志
      • 5.2.2 创建快速刷新物化视图
  • 6. 视图管理与维护
    • 6.1 查看视图信息
      • 6.1.1 视图元数据查询
      • 6.1.2 物化视图状态查询
    • 6.2 视图性能优化
      • 6.2.1 执行计划分析
      • 6.2.2 视图性能优化建议
    • 6.3 视图的修改和删除
      • 6.3.1 修改视图
      • 6.3.2 删除视图
  • 7. 视图安全与权限
    • 7.1 视图权限管理
      • 7.1.1 授予视图权限
      • 7.1.2 回收视图权限
    • 7.2 行级安全(RLS)视图
      • 7.2.1 创建安全视图
    • 7.3 视图最佳实践
      • 7.3.1 命名规范
      • 7.3.2 设计原则
  • 8. 实际应用案例
    • 8.1 企业报表视图系统
      • 8.1.1 销售业绩报表视图
      • 8.1.2 客户分析视图
    • 8.2 数据仓库视图层
      • 8.2.1 维度视图
      • 8.2.2 事实视图

正文

1. 视图基础概述

视图是Oracle数据库中的虚拟表,它是基于一个或多个表的查询结果集。视图不存储实际数据,而是存储查询定义,当访问视图时动态执行查询。

1.1 视图的概念与特点

Oracle视图
虚拟表
查询定义
数据安全
简化复杂查询
不存储实际数据
动态生成结果
基于SELECT语句
可包含多表连接
隐藏敏感列
行级安全控制
封装复杂逻辑
提供统一接口

1.2 视图的工作原理

用户查询视图
Oracle解析视图定义
合并查询条件
执行底层表查询
返回结果集
视图定义
基础表

1.3 视图的分类

Oracle视图类型
简单视图
复杂视图
物化视图
内联视图
可更新视图
基于单表
无聚合函数
支持DML操作
多表连接
包含函数/分组
只读视图
存储查询结果
定期刷新
提高查询性能
查询中的子查询
临时视图
WITH CHECK OPTION
WITH READ ONLY

2. 简单视图

简单视图基于单个表,通常可以进行DML操作。

2.1 创建简单视图

2.1.1 基本简单视图

-- 创建基本的简单视图
CREATE VIEW emp_basic_info AS
SELECT employee_id, first_name, last_name, email, hire_date
FROM employees;

-- 创建带WHERE条件的简单视图
CREATE VIEW active_employees AS
SELECT employee_id, first_name, last_name, email, phone_number, hire_date, salary
FROM employees
WHERE hire_date >= DATE '2020-01-01';

-- 创建带列别名的简单视图
CREATE VIEW emp_summary AS
SELECT employee_id AS emp_id,
       first_name || ' ' || last_name AS full_name,
       email AS email_address,
       salary AS monthly_salary,
       salary * 12 AS annual_salary,
       hire_date
FROM employees;

-- 查看视图结构
DESCRIBE emp_basic_info;

-- 查询视图数据
SELECT * FROM emp_basic_info WHERE employee_id < 110;

2.1.2 带计算列的简单视图

-- 创建包含计算列的视图
CREATE VIEW emp_salary_analysis AS
SELECT employee_id,
       first_name || ' ' || last_name AS employee_name,
       salary,
       salary * 12 AS annual_salary,
       CASE 
         WHEN salary < 5000 THEN 'Low'
         WHEN salary BETWEEN 5000 AND 10000 THEN 'Medium'
         WHEN salary > 10000 THEN 'High'
       END AS salary_grade,
       ROUND(MONTHS_BETWEEN(SYSDATE, hire_date)) AS months_employed,
       ROUND(MONTHS_BETWEEN(SYSDATE, hire_date) / 12, 1) AS years_employed
FROM employees;

-- 查询计算列视图
SELECT employee_name, salary_grade, annual_salary, years_employed
FROM emp_salary_analysis
WHERE salary_grade = 'High'
ORDER BY annual_salary DESC;

2.2 简单视图的DML操作

2.2.1 通过视图进行INSERT操作

-- 创建可插入的视图
CREATE VIEW emp_insert_view AS
SELECT employee_id, first_name, last_name, email, hire_date, job_id, department_id
FROM employees;

-- 通过视图插入数据
INSERT INTO emp_insert_view (
    employee_id, first_name, last_name, email, hire_date, job_id, department_id
) VALUES (
    999, 'John', 'Doe', 'john.doe@company.com', SYSDATE, 'IT_PROG', 60
);

-- 验证插入结果
SELECT * FROM emp_insert_view WHERE employee_id = 999;
SELECT * FROM employees WHERE employee_id = 999;

2.2.2 通过视图进行UPDATE操作

-- 通过视图更新数据
UPDATE emp_insert_view 
SET email = 'john.doe.updated@company.com',
    job_id = 'IT_ADMIN'
WHERE employee_id = 999;

-- 批量更新
UPDATE emp_salary_analysis 
SET salary = salary * 1.05
WHERE salary_grade = 'Low';

-- 验证更新结果
SELECT employee_id, employee_name, salary, salary_grade
FROM emp_salary_analysis
WHERE employee_id = 999;

2.2.3 通过视图进行DELETE操作

-- 通过视图删除数据
DELETE FROM emp_insert_view WHERE employee_id = 999;

-- 验证删除结果
SELECT COUNT(*) FROM employees WHERE employee_id = 999;

3. 复杂视图

复杂视图基于多个表或包含函数、分组等复杂操作,通常是只读的。

3.1 多表连接视图

3.1.1 员工部门视图

-- 创建员工部门完整信息视图
CREATE VIEW emp_dept_detail AS
SELECT e.employee_id,
       e.first_name || ' ' || e.last_name AS employee_name,
       e.email,
       e.salary,
       e.hire_date,
       j.job_title,
       d.department_name,
       d.manager_id AS dept_manager_id,
       dm.first_name || ' ' || dm.last_name AS dept_manager_name,
       l.city,
       l.state_province,
       c.country_name
FROM employees e
JOIN jobs j ON e.job_id = j.job_id
JOIN departments d ON e.department_id = d.department_id
LEFT JOIN employees dm ON d.manager_id = dm.employee_id
JOIN locations l ON d.location_id = l.location_id
JOIN countries c ON l.country_id = c.country_id;

-- 查询员工部门详细信息
SELECT employee_name, job_title, department_name, city, country_name
FROM emp_dept_detail
WHERE country_name = 'United States'
ORDER BY department_name, employee_name;

3.1.2 员工层级关系视图

-- 创建员工管理层级视图
CREATE VIEW emp_hierarchy AS
SELECT e.employee_id,
       e.first_name || ' ' || e.last_name AS employee_name,
       e.job_id,
       e.salary,
       e.hire_date,
       e.manager_id,
       m.first_name || ' ' || m.last_name AS manager_name,
       m.job_id AS manager_job_id,
       d.department_name,
       LEVEL AS hierarchy_level,
       SYS_CONNECT_BY_PATH(e.first_name || ' ' || e.last_name, ' -> ') AS hierarchy_path
FROM employees e
LEFT JOIN employees m ON e.manager_id = m.employee_id
JOIN departments d ON e.department_id = d.department_id
START WITH e.manager_id IS NULL
CONNECT BY PRIOR e.employee_id = e.manager_id;

-- 查询组织层级结构
SELECT LPAD(' ', (hierarchy_level - 1) * 2) || employee_name AS org_structure,
       job_id,
       manager_name,
       department_name
FROM emp_hierarchy
WHERE department_name = 'Executive'
ORDER BY hierarchy_level, employee_name;

3.2 聚合统计视图

3.2.1 部门统计视图

-- 创建部门统计汇总视图
CREATE VIEW dept_statistics AS
SELECT d.department_id,
       d.department_name,
       d.location_id,
       l.city,
       COUNT(e.employee_id) AS employee_count,
       ROUND(AVG(e.salary), 2) AS avg_salary,
       MIN(e.salary) AS min_salary,
       MAX(e.salary) AS max_salary,
       SUM(e.salary) AS total_salary,
       ROUND(STDDEV(e.salary), 2) AS salary_stddev,
       MIN(e.hire_date) AS earliest_hire_date,
       MAX(e.hire_date) AS latest_hire_date
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
LEFT JOIN locations l ON d.location_id = l.location_id
GROUP BY d.department_id, d.department_name, d.location_id, l.city;

-- 查询部门统计信息
SELECT department_name, 
       employee_count,
       avg_salary,
       total_salary,
       city
FROM dept_statistics
WHERE employee_count > 0
ORDER BY avg_salary DESC;

3.2.2 职位薪资分析视图

-- 创建职位薪资分析视图
CREATE VIEW job_salary_analysis AS
SELECT j.job_id,
       j.job_title,
       COUNT(e.employee_id) AS position_count,
       ROUND(AVG(e.salary), 2) AS avg_salary,
       ROUND(MEDIAN(e.salary), 2) AS median_salary,
       MIN(e.salary) AS min_salary,
       MAX(e.salary) AS max_salary,
       j.min_salary AS job_min_salary,
       j.max_salary AS job_max_salary,
       ROUND(AVG(e.salary) - j.min_salary, 2) AS avg_above_min,
       ROUND(j.max_salary - AVG(e.salary), 2) AS avg_below_max,
       ROUND((AVG(e.salary) - j.min_salary) / (j.max_salary - j.min_salary) * 100, 1) AS salary_position_pct
FROM jobs j
LEFT JOIN employees e ON j.job_id = e.job_id
GROUP BY j.job_id, j.job_title, j.min_salary, j.max_salary;

-- 查询职位薪资分析
SELECT job_title,
       position_count,
       avg_salary,
       median_salary,
       salary_position_pct || '%' AS position_in_range
FROM job_salary_analysis
WHERE position_count > 0
ORDER BY avg_salary DESC;

3.3 时间序列分析视图

3.3.1 年度招聘趋势视图

-- 创建年度招聘趋势分析视图
CREATE VIEW yearly_hiring_trends AS
SELECT hire_year,
       total_hired,
       LAG(total_hired, 1) OVER (ORDER BY hire_year) AS prev_year_hired,
       total_hired - LAG(total_hired, 1) OVER (ORDER BY hire_year) AS year_over_year_change,
       ROUND((total_hired - LAG(total_hired, 1) OVER (ORDER BY hire_year)) / 
             LAG(total_hired, 1) OVER (ORDER BY hire_year) * 100, 1) AS yoy_change_pct,
       avg_starting_salary,
       LAG(avg_starting_salary, 1) OVER (ORDER BY hire_year) AS prev_avg_salary,
       ROUND(avg_starting_salary - LAG(avg_starting_salary, 1) OVER (ORDER BY hire_year), 2) AS salary_change
FROM (
    SELECT EXTRACT(YEAR FROM hire_date) AS hire_year,
           COUNT(*) AS total_hired,
           ROUND(AVG(salary), 2) AS avg_starting_salary
    FROM employees
    GROUP BY EXTRACT(YEAR FROM hire_date)
);

-- 查询招聘趋势
SELECT hire_year,
       total_hired,
       CASE 
         WHEN yoy_change_pct > 0 THEN '+' || yoy_change_pct || '%'
         WHEN yoy_change_pct < 0 THEN yoy_change_pct || '%'
         ELSE 'N/A'
       END AS growth_rate,
       avg_starting_salary,
       salary_change
FROM yearly_hiring_trends
ORDER BY hire_year;

4. 视图的更新控制

4.1 WITH CHECK OPTION

WITH CHECK OPTION确保通过视图进行的DML操作符合视图的WHERE条件。

4.1.1 基本CHECK OPTION

-- 创建带CHECK OPTION的视图
CREATE VIEW high_salary_employees AS
SELECT employee_id, first_name, last_name, salary, department_id
FROM employees
WHERE salary > 8000
WITH CHECK OPTION;

-- 尝试插入符合条件的记录(成功)
INSERT INTO high_salary_employees 
VALUES (998, 'Jane', 'Smith', 9000, 60);

-- 尝试插入不符合条件的记录(失败)
-- 以下操作会产生错误:ORA-01402: view WITH CHECK OPTION where-clause violation
BEGIN
  INSERT INTO high_salary_employees 
  VALUES (997, 'Bob', 'Johnson', 5000, 60);
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('错误: ' || SQLERRM);
END;
/

-- 尝试更新为不符合条件的值(失败)
BEGIN
  UPDATE high_salary_employees 
  SET salary = 3000 
  WHERE employee_id = 998;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('更新错误: ' || SQLERRM);
END;
/

4.1.2 分级CHECK OPTION

-- 创建基础视图
CREATE VIEW dept_employees AS
SELECT employee_id, first_name, last_name, salary, department_id
FROM employees
WHERE department_id = 60;

-- 创建基于视图的视图,带CHECK OPTION
CREATE VIEW senior_dept_employees AS
SELECT employee_id, first_name, last_name, salary, department_id
FROM dept_employees
WHERE salary > 7000
WITH CHECK OPTION;

-- 测试分级检查
INSERT INTO senior_dept_employees 
VALUES (996, 'Alice', 'Brown', 8500, 60); -- 成功

-- 清理测试数据
DELETE FROM employees WHERE employee_id IN (996, 998);

4.2 WITH READ ONLY

WITH READ ONLY选项创建只读视图,禁止任何DML操作。

-- 创建只读视图
CREATE VIEW emp_salary_report AS
SELECT d.department_name,
       e.employee_id,
       e.first_name || ' ' || e.last_name AS employee_name,
       e.salary,
       e.hire_date,
       RANK() OVER (PARTITION BY d.department_id ORDER BY e.salary DESC) AS salary_rank
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WITH READ ONLY;

-- 查询只读视图
SELECT department_name, employee_name, salary, salary_rank
FROM emp_salary_report
WHERE salary_rank <= 3
ORDER BY department_name, salary_rank;

-- 尝试更新只读视图(会失败)
BEGIN
  UPDATE emp_salary_report 
  SET salary = 10000 
  WHERE employee_id = 100;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('只读视图错误: ' || SQLERRM);
END;
/

5. 物化视图

物化视图是将查询结果物理存储的视图,可以显著提高复杂查询的性能。

5.1 基本物化视图

5.1.1 创建物化视图

-- 创建基本物化视图
CREATE MATERIALIZED VIEW mv_dept_summary
BUILD IMMEDIATE
REFRESH COMPLETE ON DEMAND
AS
SELECT d.department_id,
       d.department_name,
       COUNT(e.employee_id) AS emp_count,
       ROUND(AVG(e.salary), 2) AS avg_salary,
       SUM(e.salary) AS total_salary
FROM departments d
LEFT JOIN employees e ON d.department_id = e.department_id
GROUP BY d.department_id, d.department_name;

-- 查询物化视图
SELECT * FROM mv_dept_summary 
WHERE emp_count > 0 
ORDER BY avg_salary DESC;

-- 手动刷新物化视图
EXEC DBMS_MVIEW.REFRESH('mv_dept_summary');

5.1.2 自动刷新物化视图

-- 创建自动刷新的物化视图
CREATE MATERIALIZED VIEW mv_monthly_stats
BUILD IMMEDIATE
REFRESH COMPLETE ON COMMIT
AS
SELECT EXTRACT(YEAR FROM hire_date) AS hire_year,
       EXTRACT(MONTH FROM hire_date) AS hire_month,
       COUNT(*) AS employees_hired,
       ROUND(AVG(salary), 2) AS avg_starting_salary
FROM employees
GROUP BY EXTRACT(YEAR FROM hire_date), EXTRACT(MONTH FROM hire_date);

-- 当基础表发生变化时,物化视图会自动刷新
INSERT INTO employees (employee_id, first_name, last_name, email, hire_date, job_id, salary, department_id)
VALUES (995, 'Test', 'Employee', 'test@company.com', SYSDATE, 'IT_PROG', 6000, 60);

COMMIT;

-- 查看更新后的物化视图
SELECT * FROM mv_monthly_stats 
WHERE hire_year = EXTRACT(YEAR FROM SYSDATE)
ORDER BY hire_year, hire_month;

-- 清理测试数据
DELETE FROM employees WHERE employee_id = 995;
COMMIT;

5.2 快速刷新物化视图

快速刷新只更新发生变化的部分,需要物化视图日志。

5.2.1 创建物化视图日志

-- 为基础表创建物化视图日志
CREATE MATERIALIZED VIEW LOG ON employees
WITH ROWID, SEQUENCE (employee_id, department_id, salary)
INCLUDING NEW VALUES;

CREATE MATERIALIZED VIEW LOG ON departments
WITH ROWID, SEQUENCE (department_id, department_name)
INCLUDING NEW VALUES;

5.2.2 创建快速刷新物化视图

-- 创建支持快速刷新的物化视图
CREATE MATERIALIZED VIEW mv_dept_summary_fast
BUILD IMMEDIATE
REFRESH FAST ON DEMAND
AS
SELECT d.department_id,
       d.department_name,
       COUNT(e.employee_id) AS emp_count,
       SUM(e.salary) AS total_salary,
       COUNT(*) AS row_count
FROM departments d, employees e
WHERE d.department_id = e.department_id(+)
GROUP BY d.department_id, d.department_name;

-- 进行一些更改
UPDATE employees SET salary = salary + 100 WHERE employee_id = 100;

-- 快速刷新物化视图
EXEC DBMS_MVIEW.REFRESH('mv_dept_summary_fast', 'F');

-- 查看刷新后的结果
SELECT * FROM mv_dept_summary_fast ORDER BY department_id;

6. 视图管理与维护

6.1 查看视图信息

6.1.1 视图元数据查询

-- 查看用户拥有的所有视图
SELECT view_name, text_length, read_only
FROM user_views
ORDER BY view_name;

-- 查看视图的详细定义
SELECT view_name, text
FROM user_views
WHERE view_name = 'EMP_DEPT_DETAIL';

-- 查看视图的列信息
SELECT column_name, data_type, nullable
FROM user_tab_columns
WHERE table_name = 'EMP_DEPT_DETAIL'
ORDER BY column_id;

-- 查看视图的依赖关系
SELECT name, type, referenced_name, referenced_type
FROM user_dependencies
WHERE name = 'EMP_DEPT_DETAIL';

6.1.2 物化视图状态查询

-- 查看物化视图信息
SELECT mview_name, refresh_mode, refresh_method, build_mode, 
       last_refresh_date, compile_state
FROM user_mviews;

-- 查看物化视图刷新历史
SELECT mview_name, refresh_method, start_time, end_time, elapsed_time
FROM user_mview_refresh_times
WHERE mview_name = 'MV_DEPT_SUMMARY'
ORDER BY start_time DESC;

-- 查看物化视图日志信息
SELECT log_table, master, log_trigger, rowids, primary_key, object_id
FROM user_mview_logs;

6.2 视图性能优化

6.2.1 执行计划分析

-- 分析视图查询的执行计划
EXPLAIN PLAN FOR
SELECT employee_name, department_name, salary
FROM emp_dept_detail
WHERE salary > 8000
ORDER BY salary DESC;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

-- 比较直接查询和视图查询的性能
EXPLAIN PLAN FOR
SELECT e.first_name || ' ' || e.last_name AS employee_name,
       d.department_name,
       e.salary
FROM employees e
JOIN departments d ON e.department_id = d.department_id
WHERE e.salary > 8000
ORDER BY e.salary DESC;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);

6.2.2 视图性能优化建议

-- 创建优化的视图,包含提示
CREATE OR REPLACE VIEW emp_dept_optimized AS
SELECT /*+ USE_NL(e d) INDEX(e emp_department_ix) */
       e.employee_id,
       e.first_name || ' ' || e.last_name AS employee_name,
       e.salary,
       d.department_name
FROM employees e
JOIN departments d ON e.department_id = d.department_id;

-- 为经常查询的列创建索引
CREATE INDEX emp_salary_idx ON employees(salary);
CREATE INDEX emp_dept_idx ON employees(department_id);

6.3 视图的修改和删除

6.3.1 修改视图

-- 使用OR REPLACE修改视图定义
CREATE OR REPLACE VIEW emp_basic_info AS
SELECT employee_id, 
       first_name, 
       last_name, 
       email, 
       hire_date,
       salary,  -- 新增列
       department_id  -- 新增列
FROM employees
WHERE hire_date >= DATE '2010-01-01';  -- 新增条件

-- 验证视图修改
DESCRIBE emp_basic_info;
SELECT * FROM emp_basic_info WHERE rownum <= 5;

6.3.2 删除视图

-- 删除普通视图
DROP VIEW emp_summary;

-- 删除物化视图
DROP MATERIALIZED VIEW mv_dept_summary;

-- 删除物化视图日志
DROP MATERIALIZED VIEW LOG ON employees;
DROP MATERIALIZED VIEW LOG ON departments;

-- 验证删除结果
SELECT view_name FROM user_views WHERE view_name IN ('EMP_SUMMARY');
SELECT mview_name FROM user_mviews WHERE mview_name = 'MV_DEPT_SUMMARY';

7. 视图安全与权限

7.1 视图权限管理

7.1.1 授予视图权限

-- 创建用于演示的视图
CREATE VIEW public_emp_info AS
SELECT employee_id, first_name, last_name, email, hire_date
FROM employees;

-- 授予其他用户查询权限
GRANT SELECT ON public_emp_info TO other_user;

-- 授予更新权限
GRANT UPDATE ON public_emp_info TO other_user;

-- 授予所有权限
GRANT ALL ON public_emp_info TO privileged_user;

-- 查看授予的权限
SELECT grantee, privilege, grantable
FROM user_tab_privs
WHERE table_name = 'PUBLIC_EMP_INFO';

7.1.2 回收视图权限

-- 回收特定权限
REVOKE UPDATE ON public_emp_info FROM other_user;

-- 回收所有权限
REVOKE ALL ON public_emp_info FROM other_user;

7.2 行级安全(RLS)视图

7.2.1 创建安全视图

-- 创建部门级安全视图
CREATE VIEW secure_emp_view AS
SELECT employee_id, first_name, last_name, email, salary, department_id
FROM employees
WHERE department_id IN (
    SELECT department_id 
    FROM user_dept_access 
    WHERE username = USER
);

-- 创建基于角色的视图
CREATE VIEW role_based_emp_view AS
SELECT employee_id, 
       first_name, 
       last_name, 
       email,
       CASE 
         WHEN USER IN (SELECT username FROM hr_managers) THEN salary
         ELSE NULL
       END AS salary,
       department_id
FROM employees;

7.3 视图最佳实践

7.3.1 命名规范

-- 推荐的视图命名规范
CREATE VIEW v_employee_summary AS ...;     -- 前缀 v_
CREATE VIEW emp_dept_vw AS ...;             -- 后缀 _vw
CREATE MATERIALIZED VIEW mv_sales_summary AS ...;  -- 物化视图前缀 mv_

-- 业务相关的命名
CREATE VIEW finance_employee_view AS ...;   -- 财务部门员工视图
CREATE VIEW active_projects_view AS ...;    -- 活跃项目视图

7.3.2 设计原则

视图设计最佳实践
性能考虑
安全性
维护性
可用性
避免复杂嵌套
适当使用物化视图
优化查询条件
最小权限原则
隐藏敏感数据
行级安全控制
清晰的命名规范
完整的文档
定期检查依赖
简化复杂查询
提供业务视角
标准化数据访问

8. 实际应用案例

8.1 企业报表视图系统

8.1.1 销售业绩报表视图

-- 创建销售业绩综合报表视图
CREATE VIEW sales_performance_report AS
SELECT 
    s.salesperson_id,
    e.first_name || ' ' || e.last_name AS salesperson_name,
    d.department_name,
    EXTRACT(YEAR FROM s.sale_date) AS sale_year,
    EXTRACT(QUARTER FROM s.sale_date) AS sale_quarter,
    COUNT(s.sale_id) AS total_sales,
    SUM(s.amount) AS total_revenue,
    ROUND(AVG(s.amount), 2) AS avg_sale_amount,
    RANK() OVER (
        PARTITION BY EXTRACT(YEAR FROM s.sale_date), EXTRACT(QUARTER FROM s.sale_date)
        ORDER BY SUM(s.amount) DESC
    ) AS performance_rank
FROM sales s
JOIN employees e ON s.salesperson_id = e.employee_id
JOIN departments d ON e.department_id = d.department_id
GROUP BY s.salesperson_id, e.first_name, e.last_name, d.department_name,
         EXTRACT(YEAR FROM s.sale_date), EXTRACT(QUARTER FROM s.sale_date);

8.1.2 客户分析视图

-- 创建客户价值分析视图
CREATE VIEW customer_value_analysis AS
SELECT 
    c.customer_id,
    c.customer_name,
    c.registration_date,
    COUNT(o.order_id) AS total_orders,
    SUM(o.order_amount) AS total_spent,
    ROUND(AVG(o.order_amount), 2) AS avg_order_value,
    MAX(o.order_date) AS last_order_date,
    ROUND(MONTHS_BETWEEN(SYSDATE, MAX(o.order_date)), 1) AS months_since_last_order,
    CASE 
        WHEN SUM(o.order_amount) > 10000 THEN 'VIP'
        WHEN SUM(o.order_amount) > 5000 THEN 'Premium'
        WHEN SUM(o.order_amount) > 1000 THEN 'Regular'
        ELSE 'Basic'
    END AS customer_tier,
    CASE 
        WHEN MONTHS_BETWEEN(SYSDATE, MAX(o.order_date)) <= 3 THEN 'Active'
        WHEN MONTHS_BETWEEN(SYSDATE, MAX(o.order_date)) <= 12 THEN 'At Risk'
        ELSE 'Inactive'
    END AS customer_status
FROM customers c
LEFT JOIN orders o ON c.customer_id = o.customer_id
GROUP BY c.customer_id, c.customer_name, c.registration_date;

8.2 数据仓库视图层

8.2.1 维度视图

-- 时间维度视图
CREATE VIEW dim_time AS
SELECT DISTINCT
    TRUNC(date_column) AS date_key,
    EXTRACT(YEAR FROM date_column) AS year,
    EXTRACT(QUARTER FROM date_column) AS quarter,
    EXTRACT(MONTH FROM date_column) AS month,
    EXTRACT(DAY FROM date_column) AS day,
    TO_CHAR(date_column, 'Day') AS day_name,
    TO_CHAR(date_column, 'Month') AS month_name,
    CASE WHEN TO_CHAR(date_column, 'D') IN ('1', '7') THEN 'Y' ELSE 'N' END AS is_weekend
FROM (
    SELECT hire_date AS date_column FROM employees
    UNION
    SELECT order_date FROM orders
);

-- 产品维度视图
CREATE VIEW dim_product AS
SELECT 
    p.product_id,
    p.product_name,
    p.product_code,
    c.category_name,
    c.category_id,
    p.unit_price,
    p.cost_price,
    p.unit_price - p.cost_price AS profit_margin,
    CASE 
        WHEN p.unit_price - p.cost_price > 100 THEN 'High Margin'
        WHEN p.unit_price - p.cost_price > 50 THEN 'Medium Margin'
        ELSE 'Low Margin'
    END AS margin_category
FROM products p
JOIN categories c ON p.category_id = c.category_id;

8.2.2 事实视图

-- 销售事实视图
CREATE VIEW fact_sales AS
SELECT 
    s.sale_id,
    s.sale_date,
    s.customer_id,
    s.product_id,
    s.salesperson_id,
    s.quantity,
    s.unit_price,
    s.total_amount,
    s.discount_amount,
    s.total_amount - s.discount_amount AS net_amount,
    p.cost_price * s.quantity AS total_cost,
    (s.total_amount - s.discount_amount) - (p.cost_price * s.quantity) AS profit
FROM sales s
JOIN products p ON s.product_id = p.product_id;

通过这个全面的Oracle视图教程,我们涵盖了从基础概念到高级应用的所有重要方面。视图是Oracle数据库中非常强大的工具,正确使用可以显著提高数据安全性、查询效率和系统维护性。在实际应用中,应该根据具体需求选择合适的视图类型,并遵循最佳实践来设计和维护视图。

结语
感谢您的阅读!期待您的一键三连!欢迎指正!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2398233.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

更强劲,更高效:智源研究院开源轻量级超长视频理解模型Video-XL-2

长视频理解是多模态大模型关键能力之一。尽管OpenAI GPT-4o、Google Gemini等私有模型已在该领域取得显著进展&#xff0c;当前的开源模型在效果、计算开销和运行效率等方面仍存在明显短板。近日&#xff0c;智源研究院联合上海交通大学等机构&#xff0c;正式发布新一代超长视…

2025.6.3学习日记 Nginx 基本概念 配置 指令 文件

1.初始nginx Nginx&#xff08;发音为 “engine x”&#xff09;是一款高性能的开源 Web 服务器软件&#xff0c;同时也具备反向代理、负载均衡、邮件代理等功能。它由俄罗斯工程师 Igor Sysoev 开发&#xff0c;最初用于解决高并发场景下的性能问题&#xff0c;因其轻量级、高…

【连接器专题】案例:产品测试顺序表解读与应用

在查看SD卡座连接器的规格书,一些测试报告时,你可能会看到如下一张产品测试顺序表。为什么会出现一张测试顺序表呢? 测试顺序表的使用其实定义测试环节的验证的“路线图”和“游戏规则”,本文就以我人个经验带领大家一起看懂这张表并理解其设计逻辑。 测试顺序表结构 测试…

星动纪元的机器人大模型 VPP,泛化能力效果如何?与 VLA 技术的区别是什么?

点击上方关注 “终端研发部” 设为“星标”&#xff0c;和你一起掌握更多数据库知识 VPP 利用了大量互联网视频数据进行训练&#xff0c;直接学习人类动作&#xff0c;减轻了对于高质量机器人真机数据的依赖&#xff0c;且可在不同人形机器人本体之间自如切换&#xff0c;这有望…

4000万日订单背后,饿了么再掀即时零售的“效率革命”

当即时零售转向价值深耕&#xff0c;赢面就是综合实力的强弱。 文&#xff5c;郭梦仪 编&#xff5c;王一粟 在硝烟弥漫的外卖行业“三国杀”中&#xff0c;饿了么与淘宝闪购的日订单量竟然突破了4000万单。 而距淘宝闪购正式上线&#xff0c;还不到一个月。 在大额福利优惠…

入门AJAX——XMLHttpRequest(Get)

一、什么是 AJAX AJAX Asynchronous JavaScript And XML&#xff08;异步的 JavaScript 和 XML&#xff09;。 1、XML与异步JS XML: 是一种比较老的前后端数据传输格式&#xff08;已经几乎被 JSON 代替&#xff09;。它的格式与HTML类似&#xff0c;通过严格的闭合自定义标…

5分钟申请edu邮箱【方案本周有效】

这篇文章主要展示的是成果。如果你是第1次看见我的内容&#xff0c;具体的步骤请翻看往期的两篇作品。先看更正补全&#xff0c;再看下一个。 建议你边看边操作。 【更正补全】edu教育申请通过方案 本周 edu教育邮箱注册可行方案 #edu邮箱 伟大无需多言 我已经验证了四个了…

闲谈PMIC和SBC

今天不卷&#xff0c;简单写点。 在ECU设计里&#xff0c;供电芯片选型是逃不开的话题&#xff0c;所以聊聊PMIC或者SBC的各自特点&#xff0c;小小总结下。 PMIC&#xff0c;全称Power Management Intergrated Circuits&#xff0c;听名字就很专业&#xff1a;电源管理&…

Java垃圾回收机制深度解析:从理论到实践的全方位指南

Java垃圾回收(GC)是Java虚拟机(JVM)的核心功能&#xff0c;它自动管理内存分配与回收&#xff0c;避免了C/C中常见的内存泄漏问题。本文将深入剖析Java垃圾回收的工作原理、算法实现、收集器类型及调优策略&#xff0c;助你全面掌握JVM内存管理的精髓。 一、垃圾回收基础概念 …

论文阅读:CLIP:Learning Transferable Visual Models From Natural Language Supervision

从自然语言监督中学习可迁移的视觉模型 虽然有点data/gpu is all you need的味道&#xff0c;但是整体实验和谈论丰富度上还是很多的&#xff0c;也是一篇让我多次想放弃的文章&#xff0c;因为真的是非常长的原文和超级多的实验讨论&#xff0c;隔着屏幕感受到了实验的工作量之…

在图像分析算法部署中应对流行趋势的变化|文献速递-深度学习医疗AI最新文献

Title 题目 Navigating prevalence shifts in image analysis algorithm deployment 在图像分析算法部署中应对流行趋势的变化 01 文献速递介绍 机器学习&#xff08;ML&#xff09;已开始革新成像研究与实践的诸多领域。然而&#xff0c;医学图像分析领域存在显著的转化鸿…

CAMEL-AI开源自动化任务执行助手OWL一键整合包下载

OWL 是由 CAMEL-AI 团队开发的开源多智能体协作框架&#xff0c;旨在通过动态智能体交互实现复杂任务的自动化处理&#xff0c;在 GAIA 基准测试中以 69.09 分位列开源框架榜首&#xff0c;被誉为“Manus 的开源平替”。我基于当前最新版本制作了免安装一键启动整合包。 CAMEL-…

Linux系统-基本指令(5)

文章目录 mv 指令cat 指令&#xff08;查看小文件&#xff09;知识点&#xff08;简单阐述日志&#xff09;more 和 less 指令&#xff08;查看大文件&#xff09;head 和 tail 指令&#xff08;跟查看文件有关&#xff09;知识点&#xff08;管道&#xff09;时间相关的指令&a…

C# winform教程(二)

一、基础控件 常用的基础控件主要有按钮&#xff0c;文本&#xff0c;文本输入&#xff0c;组&#xff0c;进度条&#xff0c;等等。 基础控件 名称含义详细用法Button按钮Buttoncheckbox多选按钮Combobox下拉选择groupbox组控件label标签&#xff0c;显示文字panel控件集合&a…

【仿生机器人】刀剑神域计划——仿生机器人.亚丝娜

我在做仿生机器人头&#xff0c;硬件部分已经搭建完毕&#xff0c;包括头部和颈部&#xff0c;用的23个舵机驱动机器人做表情&#xff0c;也支持头部的旋转&#xff08;就是颈部的功能&#xff09;&#xff0c;安装了摄像头在眼睛中&#xff0c;还有麦克风接受周围环境声音&…

ARM架构推理Stable Diffusiond

代码仓库&#xff1a; https://github.com/siutin/stable-diffusion-webui-docker.git Docker容器地址&#xff1a; https://hub.docker.com/r/siutin/stable-diffusion-webui-docker/tags git clone https://github.com/siutin/stable-diffusion-webui-docker.git cd stabl…

仓颉项目调试配置与多文件场景下的问题解析

1. 调试配置指南 在 VS Code 中配置好仓颉开发工具链后&#xff0c;只需按下 F5 或 Fn F5 即可启动调试。 在 CodeArts IDE for Cangjie 中&#xff0c;需先通过右上角的 编辑配置 -> 新增配置项 -> 选择 Cangjie (cjdb) Debug -> 选择 launch 模式 -> 点击 确认…

MySQL 8.0 OCP 英文题库解析(十)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题81~90 试题81:…

Python Pytest

1.Pytest用例发现规则 1.1 模块名(python文件)名必须以 test_ 开头或 _test 结尾&#xff0c;如 test_case&#xff0c;case_test&#xff0c;下划线都不能少 1.2 模块不能放在 . 开头的隐藏目录或者叫 venv的目录下&#xff0c;virtual environment&#xff0c;叫venv1都可以…

如何轻松删除 Android 上的文件(3 种方法)

Android 手机是非常强大的设备&#xff0c;可让我们存储大量的个人数据&#xff0c;从照片和视频到应用程序和文档。然而&#xff0c;随着时间的推移&#xff0c;您的设备可能会因不再需要的文件而变得混乱。删除这些文件有助于释放空间并提高性能。在本指南中&#xff0c;我们…