1.什么是视图

视图(View)是一种虚拟存在的表。其内容与真实的表相似,包含一系列带有名称的列和行数据。但是视图并不在数据库中以存储的数据的形式存在。行和列的数据来自定义视图时查询所引用的基本表,并且在具体引用视图时动态生成。

通俗的讲,视图就是一条SELECT语句执行后返回的结果集。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。

 

2.视图的作用

  • 简单:使用视图的用户完全不需要关心视图中的数据是通过什么查询得到的,视图中的数据对用户来说已经是过滤好的符合条件的结果集;
  • 安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行或某个列,但是通过视图就可以简答地实现;
  • 数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,原表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。

3.视图操作

创建视图

CREATE
[OR REPLACE]
[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
[DEFINER = { user | CURRENT_USER }]
[SQL SECURITY { DEFINER | INVOKER }]
VIEW view_name [(column_list)]
AS select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]

ALGORITHM:

MySQL有三种视图执行策略, 分别是MERGE, TEMPTABLE, UNDEFINED.

  • 使用MERGE策略,MySQL会先将输入的查询语句和视图的声明语句进行合并,然后执行合并后的语句并返回。但是如果输入的查询语句中不允许包含一些聚合函数如: MIN, MAX, SUM, COUNT, AVG, etc., or DISTINCT, GROUP BY, HAVING, LIMIT, UNION, UNION ALL, subquery。同样如果视图声明没有指向任何数据表,也是不允许的。如果出现以上任意情况, MySQL默认会使用UNDEFINED策略。
  • 使用TEMPTABLE策略,MySQL先基于视图的声明创建一张temporary table,当输入查询语句时会直接查询这张temporary table。由于需要创建temporary table来存储视图的结果集, TEMPTABLE的效率要比MERGE策略低,另外使用temporary table策略的视图是无法更新的。
  • 使用UNDEFINED策略,如果创建视图的时候不指定策略,MySQL默认使用此策略。UNDEFINED策略会自动选择使用上述两种策略中的一个,优先选择MERGE策略,无法使用则转为TEMPTABLE策略。

DEFINER

指定视图创建者。

SQL SECURITY

指定视图查询数据时的安全验证方式。

View Name

视图的名称,在MySQL中视图名和表名使用同一命名空间,这意味这视图名不能和表名重复并且要符合表名的命名规范。

Select Statement

在视图的查询声明中你可以查询所有数据库中已存在的表的数据,有以下集中规则:

  • 查询声明可以在WHERE条件中使用子查询但是不允许在FROM的来源中使用子查询。
  • 查询声明中不允许引用任何变量,包括local variables, user variables, and session variables
  • 查询声明中不允许引用prepare statement的参数。

补充: 查询声明的From中可以引用其他视图

实例解析,现有三张表:用户(user)、课程(course)、用户课程中间表(user_course),表结构及数据如下:

-- ----------------------------
-- Table structure for `course`
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`description` varchar(500) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('', 'JAVA', 'JAVA课程');
INSERT INTO `course` VALUES ('', 'C++', 'C++课程');
INSERT INTO `course` VALUES ('', 'C语言', 'C语言课程'); -- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`account` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`address` varchar(255) DEFAULT NULL,
`others` varchar(200) DEFAULT NULL,
`others2` varchar(200) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('', 'user1', '小陈', '美国', '', '');
INSERT INTO `user` VALUES ('', 'user2', '小张', '日本', '', '');
INSERT INTO `user` VALUES ('', 'user3', '小王', '中国', '', ''); -- ----------------------------
-- Table structure for `user_course`
-- ----------------------------
DROP TABLE IF EXISTS `user_course`;
CREATE TABLE `user_course` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`userid` bigint(20) NOT NULL,
`courseid` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8; -- ----------------------------
-- Records of user_course
-- ----------------------------
INSERT INTO `user_course` VALUES ('', '', '');
INSERT INTO `user_course` VALUES ('', '', '');
INSERT INTO `user_course` VALUES ('', '', '');
INSERT INTO `user_course` VALUES ('', '', '');
INSERT INTO `user_course` VALUES ('', '', '');
INSERT INTO `user_course` VALUES ('', '', '');

这时,当我们想要查询小张上的所以课程相关信息的时候,需要这样写一条长长的SQL语句,如下:

SELECT
`uc`.`id` AS `id`,
`u`.`name` AS `username`,
`c`.`name` AS `coursename`
FROM
`user` `u`
LEFT JOIN `user_course` `uc` ON ((`u`.`id` = `uc`.`userid`))
LEFT JOIN `course` `c` ON ((`uc`.`courseid` = `c`.`id`))
WHERE
u.`name` = '小张'

但是我们可以通过视图简化操作,例如我们创建视图view_user_course如下:

-- ----------------------------
-- View structure for `view_user_course`
-- ----------------------------
DROP VIEW
IF EXISTS `view_user_course`; CREATE ALGORITHM = UNDEFINED
DEFINER = `root`@`localhost`
SQL SECURITY DEFINER
VIEW `view_user_course` AS (
SELECT
`uc`.`id` AS `id`,
`u`.`name` AS `username`,
`c`.`name` AS `coursename`
FROM
(
(
`user` `u`
LEFT JOIN `user_course` `uc` ON ((`u`.`id` = `uc`.`userid`))
)
LEFT JOIN `course` `c` ON ((`uc`.`courseid` = `c`.`id`))
)
);

创建好视图之后,我们可以直接用以下SQL语句在视图上查询小张上的所以课程相关信息,同样可以得到所需结果:

SELECT
vuc.username,
vuc.coursename
FROM
view_user_course vuc
WHERE
vuc.username = '小张'

增删改数据操作

继续,我们可以尝试在视图view_user_course上做增删改数据操作,如下:

update view_user_course set username='test',coursename='JAVASCRIPT' where id=3

遗憾的是操作失败,提示错误信息如下:

[SQL] update view_user_course set username='test',coursename='JAVASCRIPT' where id=3

[Err] 1393 - Can not modify more than one base table through a join view 'demo.view_user_course'

因为不能在一张由多张关联表连接而成的视图上做同时修改两张表的操作;

那么哪些操作可以在视图上进行呢?

视图与表是一对一关系情况:如果没有其它约束(如视图中没有的字段,在基本表中是必填字段情况),是可以进行增删改数据操作;

如我们创建用户关键信息视图view_user_keyinfo,如下:

-- ----------------------------
-- View structure for `view_user_keyinfo`
-- ----------------------------
DROP VIEW
IF EXISTS `view_user_keyinfo`; CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`localhost` SQL SECURITY DEFINER VIEW `view_user_keyinfo` AS SELECT
`u`.`id` AS `id`,
`u`.`account` AS `account`,
`u`.`name` AS `username`
FROM
`user` `u`;

进行增删改操作如下,操作成功(注意user表中的其它字段要允许为空,否则操作失败):

INSERT INTO view_user_keyinfo (account, username)
VALUES
('test1', 'test1');
DELETE
FROM
view_user_keyinfo
WHERE
username = 'test1';
UPDATE view_user_keyinfo
SET username = 'updateuser'
WHERE
id = 1

视图与表是一对多关系情况:如果只修改一张表的数据,且没有其它约束(如视图中没有的字段,在基本表中是必填字段情况),是可以进行改数据操作,如以下语句,操作成功;

update view_user_course set coursename='JAVA' where id=1;
update view_user_course set username='test2' where id=3;

以下操作失败:

delete from view_user_course where id=3;
insert into view_user_course(username, coursename) VALUES('2','3');
 
 
 
 
 
 
参考:

Mysql学习笔记—视图的更多相关文章

  1. MySQL学习笔记一

    MySQL 学习笔记 一 一.数据库简单介绍 1. 按照数据库的发展时间顺序,主要出现了以下类型数据库系统: Ø 网状型数据库 Ø 层次型数据库 Ø 关系型数据库 Ø 面向对象数据库 上面4中数据库系 ...

  2. MySQL学习笔记-数据库文件

    数据库文件 MySQL主要文件类型有如下几种 参数文件:my.cnf--MySQL实例启动的时候在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还介绍了参数类 ...

  3. MySQL学习笔记-MySQL体系结构总览

    MySQL体系结构总览 不管是用哪种数据库,了解数据库的体系结构都是极为重要的.MySQL体系结构主要由数据库和数据库实例构成. 数据库:物理操作系统文件或者其它文件的集合,在mysql中,数据库文件 ...

  4. 【mysql学习笔记整理】

    /*mysql学习笔记整理*/ /*常用的数据库操作对象*/ #库的操作#创建#数据库的创建USE mysql;CREATE DATABASE db_x;#删除#删除数据库DROP DATABASE ...

  5. 一千行MySQL学习笔记 (转)

    出处:  一千行MySQL学习笔记 /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权 ...

  6. mysql basic operation,mysql总结,对mysql经常使用语句的详细总结,MySQL学习笔记

    mysql> select * from wifi_data where dev_id like "0023-AABBCCCCBBAA" ; 1.显示数据库列表.show d ...

  7. Mysql学习笔记(三)对表数据的增删改查。

    正文内容. 这一部分是最简单的,也是最麻烦的.简单是因为其实只包括增删该插四个部分.大体上看,增加数据.删除数据.修改数据.查询数据都不麻烦啊,我们日常都是常用的.这个谁不会呢?以前在培训机构学mys ...

  8. Mysql学习笔记(二)数据类型 补充

    原文:Mysql学习笔记(二)数据类型 补充 PS:简单的补充一下数据类型里的String类型以及列类型... 学习内容: 1.String类型 2.列类型存储需求 String类型: i.char与 ...

  9. Mysql学习笔记(一)数据类型

    原文:Mysql学习笔记(一)数据类型 学习内容: Mysql基本数据类型. 1.数字类型.. i.整型     Mysql数据类型             含义(有符号)     tinyint(m ...

随机推荐

  1. [转]C++11 标准新特性:Defaulted 和 Deleted 函数

    http://www.ibm.com/developerworks/cn/aix/library/1212_lufang_c11new/

  2. go context包的WithTimeout和WithCancel的使用

    1.WaitGroup 它是一种控制并发的方式,它的这种方式是控制多个goroutine同时完成. func main() { var wg sync.WaitGroup wg.Add(2) go f ...

  3. VirtualBox错误ID: PAEmode解决

    今天在导入virtualbox的虚拟机ubuntu系统时,报错,无法打开虚拟机 报错内容如下: 错误 ID: PAEmode 严重: 致命错误 The guest is trying to switc ...

  4. nginx配置事例

    #user nobody; worker_processes 4; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...

  5. docker构建测试环境

    构建测试环境首先要根据自己的需求,构建出适合自己项目的image,有了自己的image,就可以快速的搭建出来一套测试环境了. 下边就说一下构建image的两种方式. 1.DOCKFILE创建文件夹:m ...

  6. linux下安装python的第三方module

    1.首先需要有python环境 2.安装pip软件:下载地址,https://pypi.python.org/pypi/pip/6.0.8 解压pip的压缩包:sudo tar -zxvf pip-6 ...

  7. Tuning 15 Application Tuning

    oracle 是经过多年研发的, 通用的, 质量很高, 而application 是为客户定制的, 一次性的, 质量可能会出问题. 数据库的 move 的含义, 是将老表copy到新的表, 然后将新表 ...

  8. Flea Circus(Project Euler 213)

    original version hackerrank programming version 题目大意是N*N的格子,每个格子一开始有1个跳蚤,每过单位时间跳蚤会等概率向四周跳,问M秒后空格子的期望 ...

  9. javascript基本语法和变量(转)

    转载来自 阮一峰老师的文章,地址为:http://javascript.ruanyifeng.com/grammar/basic.html#toc0 1.1语句 JavaScript 程序的执行单位是 ...

  10. iOS7中弹簧式列表的制作

    本文转载至 http://www.devdiv.com/forum.php?mod=viewthread&tid=208170&extra=page%3D1%26filter%3Dty ...