当前位置: 首页 > news >正文

SQL 进阶指南:视图的创建与使用(视图语法 / 作用 / 权限控制)

在 SQL 操作中,你是否遇到过 “频繁查询多表关联的固定结果”“不想让他人看到表中的敏感字段” 这类问题?比如 “每周都要查‘技术部员工的姓名、职位、薪资’”,每次都写多表关联语句很麻烦;又比如 “给实习生开放数据查询权限,但不能让他们看到员工的身份证号、手机号”。这时候,视图(View) 就是解决这些问题的高效工具。今天我们用 “企业员工信息表” 和 “部门表” 为案例,从零学会视图的创建、使用与权限控制,代码可直接复制运行。

我整理了一些学习资料,包含专业、考试、课程等资料,还有游戏和软件的合集。

学习资料合集文档https://www.kdocs.cn/l/cjchDXwklk1B

一、先搞懂:什么是视图?

简单来说,视图就是 “一张虚拟的表”—— 它不是真实存储数据的表,而是由一个 SQL 查询语句(比如多表关联查询、字段筛选查询)定义的 “结果集”。我们可以像操作普通表一样查询视图,但视图的底层数据还是来自原表:

  • 原表数据更新时,视图的查询结果也会同步更新;
  • 视图本身不存储数据,只保存定义它的 SQL 语句。

核心价值:简化复杂查询、控制数据访问权限、保证数据一致性。

准备案例数据:员工表与部门表

为了体现视图的作用,我们创建两张关联表:“员工表(employee)” 和 “部门表(department)”,包含敏感字段(如身份证号、手机号)和关联字段(部门 ID),代码可直接运行:

-- 1. 创建部门表(存储部门信息)
CREATE TABLE department (dept_id INT PRIMARY KEY,  -- 部门ID(主键)dept_name VARCHAR(20) NOT NULL,  -- 部门名称(如技术部、销售部)dept_location VARCHAR(30) NOT NULL  -- 部门位置(如1号楼3层)
);-- 2. 创建员工表(存储员工信息,关联部门表)
CREATE TABLE employee (emp_id INT PRIMARY KEY AUTO_INCREMENT,  -- 员工ID(自增主键)emp_name VARCHAR(20) NOT NULL,  -- 员工姓名dept_id INT NOT NULL,  -- 部门ID(关联部门表)position VARCHAR(20) NOT NULL,  -- 职位(如工程师、经理)salary DECIMAL(10,2) NOT NULL,  -- 月薪id_card CHAR(18) NOT NULL,  -- 身份证号(敏感字段)phone CHAR(11) NOT NULL,  -- 手机号(敏感字段)hire_date DATE NOT NULL,  -- 入职日期-- 外键约束:确保员工的部门ID在部门表中存在FOREIGN KEY (dept_id) REFERENCES department(dept_id)
);-- 3. 插入部门数据
INSERT INTO department (dept_id, dept_name, dept_location)
VALUES
(101, '技术部', '1号楼3层'),
(102, '销售部', '1号楼5层'),
(103, '人事部', '2号楼2层');-- 4. 插入员工数据(包含3个部门的员工,含敏感字段)
INSERT INTO employee (emp_name, dept_id, position, salary, id_card, phone, hire_date)
VALUES
('张三', 101, '后端工程师', 15000.00, '110101199501011234', '13812345678', '2020-03-15'),
('李四', 101, '前端工程师', 14000.00, '110101199602022345', '13987654321', '2021-05-20'),
('王五', 102, '销售经理', 18000.00, '110101199303033456', '13711112222', '2019-01-10'),
('赵六', 102, '销售员', 12000.00, '110101199704044567', '13633334444', '2022-07-05'),
('孙七', 103, '人事专员', 10000.00, '110101199805055678', '13555556666', '2023-02-28'),
('周八', 103, '招聘主管', 13000.00, '110101199406066789', '13477778888', '2021-09-12');-- 查看原表数据(确认插入成功)
SELECT * FROM department;
SELECT * FROM employee LIMIT 3;

原表数据示例(员工表):

emp_id

emp_name

dept_id

position

salary

id_card

phone

hire_date

1

张三

101

后端工程师

15000.00

110101199501011234

13812345678

2020-03-15

2

李四

101

前端工程师

14000.00

110101199602022345

13987654321

2021-05-20

3

王五

102

销售经理

18000.00

110101199303033456

13711112222

2019-01-10

二、视图的核心操作:创建、查询、修改、删除

视图的操作语法简单,核心围绕 “创建视图(CREATE VIEW)” 和 “使用视图(SELECT)”,我们逐个讲解。

1. 创建视图(CREATE VIEW):核心语法

语法:

CREATE VIEW 视图名 AS 定义视图的SQL查询语句;

场景 1:创建 “简化多表关联” 的视图

需求:频繁需要 “查询员工姓名、部门名称、职位、薪资、入职日期”,这个需求需要关联员工表和部门表(employee JOIN department),每次写关联语句很麻烦,所以创建一个视图来简化操作。

代码:

-- 创建视图:员工-部门关联视图(简化多表查询)
CREATE VIEW emp_dept_view AS
SELECT e.emp_name AS 员工姓名,d.dept_name AS 部门名称,e.position AS 职位,e.salary AS 月薪,e.hire_date AS 入职日期
FROM employee e
JOIN department d ON e.dept_id = d.dept_id;  -- 多表关联逻辑封装在视图中
场景 2:创建 “隐藏敏感字段” 的视图

需求:给实习生开放数据查询权限,但不能让他们看到员工的身份证号、手机号,所以创建一个不含敏感字段的视图。

代码:

-- 创建视图:员工信息公开视图(隐藏敏感字段)
CREATE VIEW emp_public_view AS
SELECT emp_name AS 员工姓名,position AS 职位,salary AS 月薪,hire_date AS 入职日期
FROM employee;  -- 只包含非敏感字段
场景 3:创建 “筛选特定数据” 的视图

需求:经常需要查询 “技术部的员工信息”,所以创建一个只包含技术部员工的视图。

代码:

-- 创建视图:技术部员工视图(筛选特定部门数据)
CREATE VIEW tech_dept_emp_view AS
SELECT e.emp_name AS 员工姓名,e.position AS 职位,e.salary AS 月薪,e.hire_date AS 入职日期
FROM employee e
JOIN department d ON e.dept_id = d.dept_id
WHERE d.dept_name = '技术部';  -- 筛选条件封装在视图中

2. 查询视图:像查普通表一样简单

创建视图后,查询视图的语法和查询普通表完全一致,不用再写复杂的关联或筛选逻辑。

例子 1:查询 “员工 - 部门关联视图”

需求:查看所有员工的姓名、部门、职位、薪资。

代码:

-- 查询视图:直接用SELECT查视图,无需多表关联
SELECT * FROM emp_dept_view;

运行结果

员工姓名

部门名称

职位

月薪

入职日期

张三

技术部

后端工程师

15000.00

2020-03-15

李四

技术部

前端工程师

14000.00

2021-05-20

王五

销售部

销售经理

18000.00

2019-01-10

赵六

销售部

销售员

12000.00

2022-07-05

孙七

人事部

人事专员

10000.00

2023-02-28

周八

人事部

招聘主管

13000.00

2021-09-12

例子 2:查询 “技术部员工视图” 并筛选

需求:查看技术部入职时间在 2021 年之后的员工。

代码:

-- 查询视图时,还能加WHERE筛选条件
SELECT * FROM tech_dept_emp_view
WHERE hire_date >= '2021-01-01';

运行结果

员工姓名

职位

月薪

入职日期

李四

前端工程师

14000.00

2021-05-20

3. 修改视图:两种方式(ALTER VIEW / CREATE OR REPLACE VIEW)

如果需要修改视图的定义(比如添加字段、修改筛选条件),有两种常用方式:

方式 1:用 ALTER VIEW 修改

需求:给 “员工 - 部门关联视图” 添加 “部门位置” 字段。

代码:

-- ALTER VIEW修改视图定义
ALTER VIEW emp_dept_view AS
SELECT e.emp_name AS 员工姓名,d.dept_name AS 部门名称,d.dept_location AS 部门位置,  -- 新增字段e.position AS 职位,e.salary AS 月薪,e.hire_date AS 入职日期
FROM employee e
JOIN department d ON e.dept_id = d.dept_id;-- 验证修改结果
SELECT 员工姓名, 部门名称, 部门位置 FROM emp_dept_view;
方式 2:用 CREATE OR REPLACE VIEW 重建(推荐)

如果视图不存在,就创建;如果已存在,就覆盖修改,避免 “视图已存在” 的报错。

需求:修改 “技术部员工视图”,增加 “部门位置” 字段。

代码:

-- CREATE OR REPLACE VIEW:存在则修改,不存在则创建
CREATE OR REPLACE VIEW tech_dept_emp_view AS
SELECT e.emp_name AS 员工姓名,d.dept_name AS 部门名称,d.dept_location AS 部门位置,  -- 新增字段e.position AS 职位,e.salary AS 月薪,e.hire_date AS 入职日期
FROM employee e
JOIN department d ON e.dept_id = d.dept_id
WHERE d.dept_name = '技术部';-- 验证修改结果
SELECT * FROM tech_dept_emp_view;

4. 删除视图:DROP VIEW

如果视图不再需要,用DROP VIEW删除,不会影响原表数据(因为视图是虚拟表)。

代码:

-- 删除“员工信息公开视图”
DROP VIEW IF EXISTS emp_public_view;  -- IF EXISTS:避免“视图不存在”的报错-- 验证删除结果(会提示“表不存在”,说明删除成功)
SELECT * FROM emp_public_view;

三、视图的核心作用:3 个实用价值

通过前面的案例,我们能直观感受到视图的作用,这里总结 3 个核心价值,帮你判断什么时候该用视图:

1. 简化复杂查询,提高效率

把多表关联、复杂筛选的逻辑封装在视图中,后续查询只需要SELECT * FROM 视图名,不用重复写长 SQL。比如前面的 “员工 - 部门关联视图”,把JOIN逻辑封装后,每次查询都能节省写关联语句的时间。

2. 控制数据权限,保护敏感信息

通过视图隐藏原表中的敏感字段(如身份证号、手机号、薪资),给不同角色开放不同视图的权限,实现 “数据隔离”。比如给实习生开放 “emp_public_view”(不含敏感字段),给部门经理开放 “emp_dept_view”(含部门信息),保证数据安全。

3. 保证数据查询的一致性

如果多个场景需要用相同的查询逻辑(比如 “查询月薪大于 12000 的员工”),把这个逻辑封装在视图中,所有场景都查这个视图,避免不同人写的 SQL 逻辑不一致导致结果差异。比如创建 “high_salary_emp_view”(筛选月薪 > 12000 的员工),所有人都查这个视图,确保结果统一。

四、视图的权限控制:给不同角色分配权限

在实际工作中,视图的权限控制通常和 “数据库用户” 结合 —— 创建不同的数据库用户,给他们分配不同视图的查询权限,实现 “按需授权”。这里以 MySQL 为例,讲解基础的权限分配操作。

1. 创建数据库用户(给实习生创建用户)

-- 创建用户:用户名=intern,密码=123456(仅本地访问,@'localhost'表示本地)
CREATE USER IF NOT EXISTS 'intern'@'localhost' IDENTIFIED BY '123456';

2. 给用户分配视图的查询权限(只能查,不能改)

需求:给实习生用户(intern)分配 “tech_dept_emp_view” 和 “emp_dept_view” 的查询权限(SELECT权限),但不能分配原表的权限,也不能分配修改视图的权限。

代码:

-- 给intern用户分配两个视图的SELECT权限
GRANT SELECT ON student_management.tech_dept_emp_view TO 'intern'@'localhost';
GRANT SELECT ON student_management.emp_dept_view TO 'intern'@'localhost';-- 刷新权限,让授权生效
FLUSH PRIVILEGES;

3. 验证权限(切换到 intern 用户)

用 intern 用户登录数据库后,只能查询被授权的视图,不能查询原表(如 employee、department),也不能修改视图:

-- 能查询授权的视图(正常返回结果)
SELECT * FROM tech_dept_emp_view;-- 不能查询原表(会提示“拒绝访问”)
SELECT * FROM employee;-- 不能修改视图(会提示“没有权限”)
ALTER VIEW tech_dept_emp_view AS SELECT * FROM employee;

4. 收回权限(如需取消授权)

如果实习生离职,用REVOKE收回权限:

-- 收回intern用户对tech_dept_emp_view的SELECT权限
REVOKE SELECT ON student_management.tech_dept_emp_view FROM 'intern'@'localhost';-- 刷新权限
FLUSH PRIVILEGES;

五、视图的使用注意事项:3 个避坑点

  1. 视图不能替代原表:视图是基于原表的虚拟表,不能存储数据,修改视图的查询结果(如UPDATE 视图名 SET 字段=值)会同步修改原表数据(需谨慎!),建议尽量只用于查询,不用于修改。
  1. 复杂视图可能影响性能:如果视图包含多层嵌套(视图基于另一个视图创建)、大量JOIN或GROUP BY,查询视图时可能会变慢,建议避免过度嵌套

文章转载自:

http://rEjIoJLF.zrnqk.cn
http://jqh02Sxp.zrnqk.cn
http://1u6EZjEQ.zrnqk.cn
http://wMyYdegZ.zrnqk.cn
http://Dq7eeHSA.zrnqk.cn
http://MrujvrbW.zrnqk.cn
http://HmcBXIXp.zrnqk.cn
http://8gn24tiV.zrnqk.cn
http://msTty4tD.zrnqk.cn
http://ewgXkwyY.zrnqk.cn
http://tZkUvTLD.zrnqk.cn
http://QGbiQrxz.zrnqk.cn
http://ujNfoAXK.zrnqk.cn
http://pugw9wzB.zrnqk.cn
http://YqEdY6VQ.zrnqk.cn
http://kMBYaZ38.zrnqk.cn
http://jumh41Dt.zrnqk.cn
http://IgQbcfa9.zrnqk.cn
http://u1NWJE9s.zrnqk.cn
http://RDvCPEnD.zrnqk.cn
http://j177yhpE.zrnqk.cn
http://7C4Aqn6q.zrnqk.cn
http://mCkdOL2u.zrnqk.cn
http://9K0F6pQ5.zrnqk.cn
http://7AhepJWv.zrnqk.cn
http://n7hJVfV7.zrnqk.cn
http://6Kuu6CYz.zrnqk.cn
http://V8Bhll9b.zrnqk.cn
http://5YC7dKyk.zrnqk.cn
http://01neMsnV.zrnqk.cn
http://www.dtcms.com/a/369980.html

相关文章:

  • SQL 实战指南:电商订单数据分析(订单 / 用户 / 商品表关联 + 统计需求)
  • 附050.Kubernetes Karmada Helm部署联邦及使用
  • 【PCIe EP 设备入门学习专栏 -- 8 PCIe EP 架构详细介绍】
  • STM32HAL 快速入门(十九):UART 编程(二)—— 中断方式实现收发及局限分析
  • 【星闪】Hi2821 | PWM脉宽调制模块 + 呼吸灯例程
  • 具身智能模拟器:解决机器人实机训练场景局限与成本问题的创新方案
  • 【嵌入式】【科普】AUTOSAR学习路径
  • 大麦APP抢票-核心
  • Linux笔记---TCP套接字编程
  • SQL面试题及详细答案150道(81-100) --- 子查询篇
  • CentOS系统停服,系统迁移Ubuntu LTS
  • 基于Spring Boot的幼儿园管理系统
  • 《sklearn机器学习——聚类性能指标》Fowlkes-Mallows 得分
  • STAR-CCM+|雷诺数回顾
  • 设计整体 的 序分(三“释”)、正宗分(双“门”)和流通分(统一的通行表达式) 之3 “自明性”(腾讯元宝 之2)
  • MySQL集群高可用架构之组复制 (MGR)
  • GPT-5发布:统一智能体时代的开启——从“工具”到“协作者”的范式跃迁
  • 【iOS】push 和 present
  • 大数据毕业设计选题推荐-基于大数据的宫颈癌风险因素分析与可视化系统-Spark-Hadoop-Bigdata
  • 【xss基本介绍】
  • 无需公网IP,电脑随时与异地飞牛同步互联保持数据一致性
  • HTML 列表类型
  • 怎么用 tauri 创建一个桌面应用程序(Electron)
  • Redis《RedisSerializer》
  • 云原生的12个要素是什么?
  • uni-app倒计时公共组件 封装,倒计时组件
  • AI驱动的软件测试:革命性的自动化、缺陷检测与实验优化
  • 打包 Uniapp
  • Vue 项目性能优化实战
  • C++ Lambda 表达式完整指南