MySQL基础 - 视图示例
视图是由数据库中的一个表或多个表导出的虚拟表,其作用是方便用户对数据的操作。
概念
视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,数据库中只存放了视图的定义,而并没有存放视图中的数据,这些数据存放在原来的表中。使用视图查询数据时,数据库系统会从原来的表中取出对应的数据。因此,视图中的数据是依赖于原来的表中的数据的。一旦表中的数据发生改变,显示在视图中的数据也会发生改变。同样对视图的更新,会影响到原来表的数据。
视图是存储在数据库中的查询的SQL语句,它主要出于两种原因**:安全原因**,视图可以隐藏一些数据,例如,员工信息表,可以用视图只显示姓名、工龄、地址,而不显示社会保险号和工资数等;另一个原因是可使复杂的查询易于理解和使用。这个视图就像一个“窗口”,从中只能看到你想看的数据列。这意味着你可以在这个视图上使用SELECT *,而你看到的将是你在视图定义里给出的那些数据列。
作用
视图是在原有表或者视图的基础上重新定义的虚拟表,这可以从原有的表上选取对用户有用的信息,忽略次要信息,其作用类似于筛选。视图的作用归纳为如下几点:
使操作简单化
视图需要达到的目的就是所见即所需。视图不仅可以简化用户对数据的理解,也可以简化他们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
增加数据的安全性
通过视图,用户只能查询和修改指定的数据。指定数据之外的信息,用户根本接触不到。这样可以防止敏感信息被未授权的用户查看,增强机密信息的安全性。
提高表的逻辑独立性
视图可以屏蔽原有表结构变化带来的影响。例如原有表增加列和删除未被引用的列,对视图不会造成影响。同样,如果修改表中的某些列,可以使用修改视图来解决这些列带来的影响。
基本操作
创建视图
创建视图是指在已经存在的数据库表上建立视图。视图可以建立在一张表中,也可以建立在多张表中。
查看创建视图的权限
创建视图需要具有CREATE VIEW的权限。同时应该具有查询涉及的列的SELECT权限。可以使用SELECT语句来查询这些权限信息。查询语法如下:
SELECT Select_priv,Create_view_priv FROM mysql.user WHERE user='用户名';
参数说明:
Select_priv:属性表示用户是否具有SELECT权限,Y表示拥有SELECT权限,N表示没有。
Create_view_priv:属性表示用户是否具有CREATE VIEW权限;
mysql.user:表示MySQL数据库下面的user表。
用户名:参数表示要查询是否拥有权限的用户,该参数需要用单引号引起来。
示例:查询MySQL中root用户是否具有创建视图的权限。
MySQL中,创建视图是通过CREATE VIEW语句实现的。其语法如下:
CREATE [OR REPLACE] [ALGORITHM={UNDEFINED|MERGE|TEMPTABLE}]
VIEW 视图名[(属性清单)]
AS SELECT语句
[WITH [CASCADED|LOCAL] CHECK OPTION];
2
3
4
参数说明:
ALGORITHM:可选项,表示视图选择的算法。
视图名:表示要创建的视图名称。
属性清单:可选项,指定视图中各个属性的名词,默认情况下与SELECT语句中的查询的属性相同。
SELECT语句:表示一个完整的查询语句,将查询记录导入视图中。
WITH CHECK OPTION:可选项,表示更新视图时要保证在该视图的权限范围之内。
例:创建视图。
CREATE VIEW view_student AS SELECT id,name,class FROM student;
例:创建视图同时,指定属性清单。
CREATE VIEW view_student1(stu_id,stu_name,stu_class) AS SELECT id,name,class FROM student;
CREATE OR REPLACE VIEW view_student1(stu_id,stu_name,stu_class) AS SELECT id,name,class FROM student;
2
3
创建视图时需要注意以下几点:
运行创建视图的语句需要用户具有创建视图(create view)的权限,若加了[or replace]时,还需要用户具有删除视图(drop view)的权限;
select语句不能包含from子句中的子查询;
select语句不能引用系统或用户变量;
select语句不能引用预处理语句参数;
在存储子程序内,定义不能引用子程序参数或局部变量;
在定义中引用的表或视图必须存在。但是,创建了视图后,能够舍弃定义引用的表或视图。要想检查视图定义是否存在这类问题,可使用check table语句;
在定义中不能引用temporary表,不能创建temporary视图;
在视图定义中命名的表必须已存在;
不能将触发程序与视图关联在一起;
在视图定义中允许使用order by,但是,如果从特定视图进行了选择,而该视图使用了具有自己order by的语句,它将被忽略。
修改视图
修改视图是指修改数据库中已存在的表的定义。当基本表的某些字段发生改变时,可以通过修改视图来保持视图和基本表之间一致。MySQL中通过CREATE OR REPLACE VIEW语句和ALTER VIEW语句来修改视图。
示例:修改视图
mysql> CREATE OR REPLACE
VIEW view_student1(stu_id,stu_name,stu_class) AS SELECT id,name,class FROM student;
Query OK, 0 rows affected
mysql> select * from view_student1;
+--------+----------+-----------+
| stu_id | stu_name | stu_class |
+--------+----------+-----------+
| 1001 | Jason | 1 |
| 1002 | Helen | 3 |
| 1003 | Steve | 5 |
| 1004 | Hanna | 1 |
| 1005 | Bob | 3 |
| 1006 | John | 7 |
| 1007 | Walln | 8 |
+--------+----------+-----------+
7 rows in set
mysql> ALTER VIEW view_student1 AS SELECT id,name,class FROM student where id in (select id from student );
Query OK, 0 rows affected
mysql> select * from view_student1;
+------+-------+-------+
| id | name | class |
+------+-------+-------+
| 1001 | Jason | 1 |
| 1002 | Helen | 3 |
| 1003 | Steve | 5 |
| 1004 | Hanna | 1 |
| 1005 | Bob | 3 |
| 1006 | John | 7 |
| 1007 | Walln | 8 |
+------+-------+-------+
7 rows in set
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
说明:ALTER VIEW语句改变了视图的定义,该语句与CREATE OR REPLACE VIEW语句有着同样的限制,如果删除并重新创建一个视图,就必须重新为它分配权限。
删除视图
删除视图是指删除数据库中已存在的视图。删除视图时,只能删除视图的定义,不会删除数据。MySQL中,使用DROP VIEW语句来删除视图。但是,用户必须拥有DROP权限。
例:删除视图。
DROP VIEW IF EXISTS view_student;
## 查看视图
查看视图是指查看数据库中已存在的视图的定义。
例:查看视图。
mysql> describe view_student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | NULL | |
| name | varchar(30) | YES | | NULL | |
| class | int(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
3 rows in set
2
3
4
5
6
7
8
9
视图练习
员工表和数据:
CREATE TABLE employee(
ID INT PRIMARY KEY AUTO_INCREMENT,
NAME CHAR(30) NOT NULL,
SEX CHAR(2) NOT NULL,
AGE INT NOT NULL,
DEPARTMENT CHAR(10) NOT NULL,
SALARY INT NOT NULL,
HOME CHAR(30),
MARRY CHAR(2) NOT NULL DEFAULT '否',
HOBBY CHAR(30)
);
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'李红','女',20,'人事资源部','7000','浙江','否','网球');
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'姜文','女',21,'人事资源部','9000','北京','是','看书');
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'李楠','男',22,'产品研发部','8000','上海','否','音乐');
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'潇潇','女',23,'产品研发部','9000','重庆','否','游泳');
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'王亮','女',24,'产品研发部','9000','四川','是','足球');
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'程默','男',25,'业务销售部','8500','福建','否','游戏');
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'陆明','男',26,'业务销售部','10000','山西','否','篮球');
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'韩路','男',26,'业务销售部','15000','江苏','否','足球');
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
具体的表内容如下:
员工信息表和数据:
CREATE TABLE employee_detail(
ID INT PRIMARY KEY,
POS CHAR(10) NOT NULL,
EXPERENCE CHAR(10) NOT NULL,
CONSTRAINT `FK_ID` FOREIGN KEY(ID) REFERENCES employee(ID)
);
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(1,'人事管理','工作二年');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(2,'人事招聘','工作二年');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(3,'初级工程师','工作一年');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(4,'中级工程师','工作二年');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(5,'高级工程师','工作三年');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(6,'销售代表','工作二年');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(7,'销售经理','工作一年');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(8,'销售总监','工作一年');
2
3
4
5
6
7
8
9
10
11
12
13
14
15
具体的表内容如下:
单表上创建视图:
CREATE VIEW V_VIEW1(ID, NAME, SEX, AGE,DEPARTMENT) AS SELECT ID, NAME, SEX, AGE,DEPARTMENT FROM employee;
显示结果
SELECT * FROM V_VIEW1;
多表上创建视图:
CREATE VIEW V_VIEW2(ID, NAME, SEX, AGE,DEPARTMENT,POS,EXPERENCE) AS SELECT a.ID, a.NAME, a.SEX, a.AGE,a.DEPARTMENT,b.POS,b.EXPERENCE FROM employee a,employee_detail b WHERE a.ID=b.ID;
显示结果
SELECT * FROM V_VIEW2;
修改视图中的数据,会影响原有表数据变化,例如:
UPDATE V_VIEW2 SET POS='高级工程师' WHERE NAME='李楠';
修改原始表中的数据,会影响视图的变化,例如:
INSERT INTO employee(ID, NAME, SEX, AGE,DEPARTMENT, SALARY, HOME, MARRY, HOBBY) VALUES(NULL,'韩寒','男',24,'产品研发部','8000','上海','否','音乐');
INSERT INTO employee_detail(ID,POS,EXPERENCE) VALUES(9,'初级工程师','工作一年');
2