使用过微软 Access 小型数据库管理系统的朋友可能永远不会忘记查询的概念,它也是二级 Access 考试的重中之重。掌握了查询部分,二级过关就有了绝对把握。查询之所以重要,其中一个主要原因在于其灵活性。创建数据库表初期,我们可以建立一些基础表格,但是由于现实需求的复杂性,很难一下设计出符合所有需求的所有表格,例如有时需要基于一些字段很多的大表创建一些临时性的若干 "子表"。这种所谓的'子表',就可以使用查询来设计实现。从本质上讲,这种查询只是存储了创建这些查询的SQL语句,并没有生成独立的查询对应的'子表'。当然,这也在一定程度上节约了存储。
在例如 MySQL,MS SQL 及 Oracle 等大型关系数据库中,你很难找到查询的概念。相反,你看到的是视图;它正是类似于 Access 中查询的东西。因此,这种视图在数据库设计中的位置也是不言而喻的。
一. 视图概念
MySQL 视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
对其中所引用的基础表来说,MySQL 视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。
实际上,视图是存储在数据库中的查询的 sql 语句,它主要出于两种原因:安全原因,视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等,另一原因是可使复杂的查询易于理解和使用。
实用开发中,视图一般是从一个或多个表或视图中导出的表,其结构和数据是建立在对表的查询基础上的。和表一样,视图也是包括几个被定义的数据列和多个数据行,但就本质而言这些数据列和数据行来源于其所引用的表。
所以,MySQL 视图不是真实存在的基础表而是一张虚表,视图所对应的数据并不实际地以视图结构存储在数据库中,而是存储在视图所引用的表中。
视图一经定义便存储在数据库中,与其相对应的数据并没有像表那样又在数据库中再存储一份,通过视图看到的数据只是存放在基本表中的数据。对视图的操作与对表的操作一样,可以对其进行查询、修改 (有一定的限制)、删除。
当对通过视图看到的数据进行修改时,相应的基本表的数据也要发生变化,同时,若基本表的数据发生变化,则这种变化也可以自动地反映到视图中。
视图有很多优点,主要表现在:
数据的物理独立性是指用户的应用程序不依赖于数据库的物理结构。数据的逻辑独立性是指当数据库重构造时,如增加新的关系或对原有的关系增加新的字段,用户的应用程序不会受影响。层次数据库和网状数据库一般能较好地支持数据的物理独立性,而对于逻辑独立性则不能完全的支持。
在关许数据库中,数据库的重构造往往是不可避免的。重构数据库最常见的是将一个基本表 "垂直" 地分成多个基本表。例如:将学生关系 Student(Sno,Sname,Ssex,Sage,Sdept),
分为 SX(Sno,Sname,Sage)和 SY(Sno,Ssex,Sdept)两个关系。这时原表 Student 为 SX 表和 SY 表自然连接的结果。如果建立一个视图 Student:
- CREATE VIEW Student(Sno,Sname,Ssex,Sage,Sdept)AS SELECT SX.Sno,SX.Sname,SY.Ssex,SX.Sage,SY.Sdept FROM SX,SY WHERE SX.Sno=SY.Sno;
这样尽管数据库的逻辑结构改变了(变为 SX 和 SY 两个表了),但应用程序不必修改,因为新建立的视图定义为用户原来的关系,使用户的外模式保持不变,用户的应用程序通过视图仍然能够查找数据。
当然,视图只能在一定程度上提供数据的逻辑独立,比如由于视图的更新是有条件的,因此应用程序中修改数据的语句可能仍会因为基本表构造的改变而改变。
二. 创建 MySQL 视图——create view
通过该语句可以创建视图,若给定了 [or replace],则表示当已具有同名的视图时,将覆盖原视图。select_statement 是一个查询语句,这个查询语句可从表或其它的视图中查询。视图属于数据库,因此需要指定数据库的名称,若未指定时,表示在当前的数据库创建新视图。
表和数据库共享数据库中相同的名称空间,因此,数据库不能包含相同名称的表和视图,并且,视图的列名也不能重复。
本例创建一个产品表(product)和一个购买记录表(purchase),再通过 MySQL 视图 purchase_detail 查询出购买的详细信息。
- create table product
- (
- product_id int not null,
- name varchar(50) not null,
- price double not null );
- insert into product values(1, 'apple ', 5.5);
- create table purchase
- (
- id int not null,
- product_id int not null,
- qty int not null default 0,
- gen_time datetime not null );
- insert into purchase values(1, 1, 10, now());
- create view purchase_detail as select product.name as name, product .price as price, purchase.qty as qty,
- product .price * purchase.qty as total_value from product,
- purchase where product.product_id = purchase.product_id;
创建成功后,输入:select * from purchase_detail;
运行效果如下:
+-------+-------+-----+-------------+
| name | price | qty | total_value |
+-------+-------+-----+-------------+
| apple | 5.5 | 10 | 55 |
+-------+-------+-----+-------------+
1 row in set (0.01 sec)
注意事项归纳:
创建视图存在如下注意事项:
(1) 运行创建视图的语句需要用户具有创建视图(crate view)的权限,若加了 [or replace] 时,还需要用户具有删除视图(drop view)的权限;
(2) select 语句不能包含 from 子句中的子查询;
(3) select 语句不能引用系统或用户变量;
(4) select 语句不能引用预处理语句参数;
(5) 在存储子程序内,定义不能引用子程序参数或局部变量;
(6)在定义中引用的表或视图必须存在。但是,创建了 MySQL 视图后,能够舍弃定义引用的表或视图。要想检查视图定义是否存在这类问题,可使用 check table 语句;
(7) 在定义中不能引用 temporary 表,不能创建 temporary 视图;
(8) 在视图定义中命名的表必须已存在;
(9) 不能将触发程序与视图关联在一起;
(10) 在视图定义中允许使用 order by,但是,如果从特定视图进行了选择,而该视图使用了具有自己 order by 的语句,它将被忽略。
三. 修改 MySQL 视图——alter view
将上一小节中中创建的视 purchase_detail 进行修改,去掉 qty 列,语句如下:
- alter view purchase_detail as select product.name as name,
- product .price as price,
- product .price * purchase.qty as total_value from product,
- purchase where product.product_id = purchase.product_id;
四,重要参考文章
来源: