视图
以例子来说明:
SELECT salaries.emp_no, dept_emp.dept_no, salary, dept_name FROM salaries, dept_emp, departments WHERE salaries.emp_no = dept_emp.emp_no AND dept_emp.dept_no = departments.dept_no AND salary = 158220;
从三张表中获取薪水为158220的员工的id,部门id,薪水和部门名称。
如果使用视图,这段语句就会变成:
SELECT salaries.emp_no, dept_emp.dept_no, salary, dept_name FROM salary_for_department WHERE salary = 158220;
视图的作用相当于是对整个查询语句中复杂部分做了封装,只需要修改过滤部分和查询的关键字。
为什么使用视图
- 重用SQL语句
- 简化复杂的SQL操作,在编写完查询后可以方便的重用它。
- 使用表的组成部分而不是整个表
- 保护数据。可以授予用户表的特定部分的访问权限而不是整个表的访问权限。
- 更改数据格式和表示。视图可以返回与底层表的表示和格式不同的数据。
创建完视图后,它的用法和表数据几乎相同,可以对视图执行SELECT操作,排序和过滤数据,也可以进行联结到其他视图或表,甚至能添加和更新数据。
视图的规则和限制
- 与表一样,视图必须唯一命名
- 对于可以创建的视图没有数量限制
- 为了创建视图,必须具有足够的访问权限
- 视图可以嵌套,即可以利用其它视图中检索数据的查询来构造一个视图,类似于子查询
- ORDER BY可以用在视图中,但如果从该视图检索数据SELECT中也包含ORDER BY,那么该视图中的ORDER BY将会被覆盖
- 视图不能索引,也不能有关联的触发器或默认值
- 视图可以和表一起使用
使用视图
视图的用法:
- 视图用
CREATE VIEW
语句来创建 - 使用
SHOW CREATE VIEW viewname
来查看创建视图的语句 - 使用
DROP
删除视图,其语法为DROP VIEW viewname
- 更新视图时,可以先使用
DROP
在使用CREATE
,也可以用CREATE OR REPLACE VIEW
。如果要更新的视图不存在,则第二条语句会创建一个视图。如果要更新的视图存在,第二条语句会替换该视图。
利用视图简化复杂的联结
以例子说明:
CREATE VIEW salary_for_department AS SELECT salaries.emp_no, dept_emp.dept_no, salary, dept_name FROM salaries, dept_emp, departments WHERE salaries.emp_no = dept_emp.emp_no AND dept_emp.dept_no = departments.dept_no;
该语句创建了名为salary_for_department
的视图,它将返回所有员工的id,部门id,薪水和部门名称。
如果检索薪水为158220的员工:
SELECT emp_no, dept_no, salary, dept_name FROM salary_for_department WHERE salary = 158220;
会发现,在使用视图时候不需要指定emp_no
,dept_no
属于哪张表。
+--------+---------+--------+-----------+
| emp_no | dept_no | salary | dept_name |
+--------+---------+--------+-----------+
| 43624 | d007 | 158220 | Sales |
+--------+---------+--------+-----------+
1 row in set (1.77 sec)
用视图过滤不想要的数据
CREATE VIEW sales_departments_salary AS SELECT salaries.emp_no, salary, dept_name FROM salaries, dept_emp, departments WHERE salaries.emp_no = dept_emp.emp_no AND dept_emp.dept_no = departments.dept_no AND dept_name = 'Sales';
创建一个销售部门的员工id,部门id,薪水列表。
SELECT * FROM sales_departments_salary;
+--------+--------+-----------+
| emp_no | salary | dept_name |
+--------+--------+-----------+
| 10002 | 65828 | Sales |
| 10002 | 65909 | Sales |
| 10002 | 67534 | Sales |
| 10002 | 69366 | Sales |
| 10002 | 71963 | Sales |
+--------+--------+-----------+
5 rows in set (0.00 sec)
如果在使用视图的时候额外添加了WHERE子句,那么视图内的子句会与视图外的子句自动组合。
更新视图
更新视图有一个前提条件,如果在视图中无法确定源数据表,那么将无法更新。也就是说如果视图中包含以下语句将不允许更新:
- 分组(使用GROUP BY和HAVING)
- 联结
- 子查询
- 并
- 聚集函数(MIN(),SUM(),COUNT()等)
- DISTINCT
- 导出列
小结:
- 视图相当于是对MySQL的SELECT层语句做了次封装,可以复用。相当于是一个虚拟的表,功能与数据表无异。
- 视图的更新条件还是蛮苛刻的,很少有能更新的场景。所以一般视图是用于检索,基本不用于更新。