前言
MySQL中的视图(View)是一种虚拟表,它不存储数据,而是存储一个SQL查询语句。视图可以看作是存储在数据库中的一个查询,当用户查询视图时,数据库会执行视图中定义的查询语句,并返回结果。视图可以简化复杂的查询,提高数据的安全性,以及实现数据的逻辑独立性。
以下是视图的一些基本特点和用途:
-
简化复杂查询:通过创建视图,可以将复杂的查询语句封装起来,用户只需要查询视图即可得到所需的数据,无需每次都编写复杂的SQL语句。
-
数据安全:通过视图可以限制用户对数据的访问。例如,可以创建一个只包含特定列的视图,这样用户只能看到这些列的数据,而看不到其他敏感信息。
-
逻辑独立性:视图可以提供一个与底层表结构不同的数据视图。当底层表结构发生变化时,只要视图的定义保持不变,用户通过视图看到的数据结构就不会受到影响。
-
数据汇总:视图可以用来汇总数据,例如,可以创建一个视图来显示每个月的销售总额,而不需要每次都编写计算总和的查询。
-
数据更新限制:视图可以限制对数据的更新操作。默认情况下,视图是不可更新的,但可以通过特定的语法创建可更新的视图。
创建视图的基本语法如下:
CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
其中,view_name
是视图的名称,SELECT
语句定义了视图中包含的数据,table_name
是视图所基于的表的名称,WHERE
子句是可选的,用于限制视图中显示的数据。
例如,创建一个名为 sales_by_month
的视图,用于显示每个月的销售总额:
CREATE VIEW sales_by_month AS
SELECT MONTH(order_date) AS month, SUM(amount) AS total_sales
FROM orders
GROUP BY MONTH(order_date);
使用视图时,只需执行如下查询:
SELECT * FROM sales_by_month;
这将返回每个月的销售总额。
需要注意的是,视图虽然提供了很多便利,但也有其局限性。例如,视图不能用来创建索引,而且在某些情况下,视图的性能可能不如直接查询底层表。此外,视图的使用也受到数据库权限的限制。在设计和使用视图时,需要根据具体的应用场景和需求来决定是否使用视图以及如何使用视图。
案例
拟创建一个数据库,其中包含的表格如下:
- 读者表
- 读者类型表
- 借阅表
- 库存表
- 图书表
L_view1
执行如下查询:
CREATE VIEW L_view1 AS SELECT
`读者表`.`读者编号`,
`读者表`.`姓名`,
`读者类型表`.`类名`,
`读者类型表`.`可借天数`,
`读者类型表`.`可借数量`
FROM
`读者表`
JOIN `读者类型表` ON `读者表`.`类别号` = `读者类型表`.`类别号`;
这段SQL语句创建了一个名为 L_view1
的视图,它将两个表(读者表
和 读者类型表
)通过内连接(INNER JOIN)合并,并从合并后的结果中选择特定的列。以下是该SQL语句的详细解释:
-
CREATE VIEW L_view1 AS
:这部分声明了创建视图的命令,L_view1
是新视图的名称。 -
SELECT
:紧随其后的是一个选择列表,指定了视图中将包含的列。这些列来自两个不同的表:读者表
.读者编号
:从读者表
中选择读者编号
列。读者表
.姓名
:从读者表
中选择姓名
列。读者类型表
.类名
:从读者类型表
中选择类名
列。读者类型表
.可借天数
:从读者类型表
中选择可借天数
列。读者类型表
.可借数量
:从读者类型表
中选择可借数量
列。
-
FROM
:指定了视图数据的来源表。这里有两个表:读者表
:这是包含读者信息的表,如读者编号和姓名。读者类型表
:这是包含读者类型信息的表,如类名、可借天数和可借数量。
-
JOIN
:使用内连接(INNER JOIN)来合并两个表。内连接是基于两个表中具有相同值的列进行连接的。 -
ON
:指定了连接条件,即读者表
中的类别号
列与读者类型表
中的类别号
列相匹配。这意味着只有当两个表中类别号
相同时,相应的行才会被包含在视图中。
综上所述,这个视图 L_view1
提供了一个合并了读者信息和读者类型信息的虚拟表,它使得查询读者的详细信息(包括读者的编号、姓名、所属的读者类型以及该类型的借阅规则)变得非常方便。通过这个视图,用户可以轻松地查询到读者的详细信息,而无需每次都编写复杂的连接查询语句。
最后可以执行如下查询来测试:
SELECT `读者编号`, `姓名`, `可借天数`, `可借数量` FROM l_view1;
L_view2
执行如下查询:
CREATE VIEW L_view2 AS SELECT
`借阅表`.`借阅号`,
`库存表`.`书号`,
`读者表`.`姓名`,
`借阅表`.`借阅日期`,
`借阅表`.`还书日期`
FROM
`借阅表`
JOIN `读者表` ON `借阅表`.`读者编号` = `读者表`.`读者编号`
JOIN `库存表` ON `借阅表`.`条码` = `库存表`.`条码`;
这段SQL语句创建了一个名为 L_view2
的视图,它将三个表(借阅表
、读者表
和 库存表
)通过两个内连接(INNER JOIN)合并,并从合并后的结果中选择特定的列。以下是该SQL语句的详细解释:
-
CREATE VIEW L_view2 AS
:这部分声明了创建视图的命令,L_view2
是新视图的名称。 -
SELECT
:紧随其后的是一个选择列表,指定了视图中将包含的列。这些列来自三个不同的表:借阅表
.借阅号
:从借阅表
中选择借阅号
列。库存表
.书号
:从库存表
中选择书号
列。读者表
.姓名
:从读者表
中选择姓名
列。借阅表
.借阅日期
:从借阅表
中选择借阅日期
列。借阅表
.还书日期
:从借阅表
中选择还书日期
列。
-
FROM
:指定了视图数据的来源表。这里涉及三个表:借阅表
:这是包含借阅信息的表,如借阅号、借阅日期和还书日期。读者表
:这是包含读者信息的表,如读者的姓名。库存表
:这是包含图书库存信息的表,如书号。
-
JOIN
:使用内连接(INNER JOIN)来合并表。这里有两次内连接:- 第一次内连接是
借阅表
和读者表
,基于借阅表
.读者编号
和读者表
.读者编号
相等的条件。 - 第二次内连接是
借阅表
和库存表
,基于借阅表
.条码
和库存表
.条码
相等的条件。
- 第一次内连接是
通过这个视图,用户可以方便地查询到借阅记录的详细信息,包括借阅号、书号、读者姓名、借阅日期和还书日期。这个视图将借阅信息、读者信息和库存信息整合在一起,使得查询借阅记录时不必分别查询三个表,提高了数据检索的效率和便利性。
视图 L_view2
为图书馆管理系统中的借阅记录查询提供了一个方便的接口,使得管理员或用户可以快速获取到借阅相关的详细信息。同时,通过视图的使用,可以隐藏底层表的复杂性,简化查询操作,提高数据的安全性。
最后可以执行如下查询来测试:
SELECT * FROM l_view2 WHERE `还书日期` IS NULL;
L_view3
执行如下查询:
CREATE VIEW L_view3 AS SELECT
*
FROM
`借阅表`
WHERE
`借阅状态` = '借阅'
OR `借阅状态` = '已还'
WITH CHECK OPTION;
这段SQL语句创建了一个名为 L_view3
的视图,它从 借阅表
中选择所有列,并且只包含那些借阅状态为“借阅”或“已还”的记录。此外,它使用了 WITH CHECK OPTION
子句,这确保了通过视图进行的任何更新或插入操作都必须满足视图的定义条件。以下是该SQL语句的详细解释:
-
CREATE VIEW L_view3 AS
:这部分声明了创建视图的命令,L_view3
是新视图的名称。 -
SELECT * FROM
:选择借阅表
中的所有列。*
是一个通配符,表示选择表中的所有列。 -
WHERE
:指定了一个条件,只有满足这个条件的记录才会被包含在视图中。条件是借阅状态
列的值必须等于 ‘借阅’ 或 ‘已还’。 -
WITH CHECK OPTION
:这个子句确保了通过视图进行的任何更新或插入操作都必须满足视图的定义条件。如果尝试插入或更新一条记录,而该记录的借阅状态
不是 ‘借阅’ 或 ‘已还’,则操作将失败,因为这违反了视图的定义。
总结来说,L_view3
视图提供了一个方便的接口,允许用户或应用程序查询或操作 借阅表
中的记录,但只限于那些借阅状态为 ‘借阅’ 或 ‘已还’ 的记录。此外,WITH CHECK OPTION
确保了通过视图进行的任何数据修改操作都必须符合视图的定义,从而维护了数据的一致性和完整性。这个视图对于实现数据访问控制和简化数据操作非常有用,特别是在需要限制对某些数据的访问或更新时。
最后可以执行如下查询来测试:
INSERT INTO l_view3 VALUES(100010, 411112, 2001, '2020-10-18', NULL, '借阅');
UPDATE l_view2 SET `借阅号` = CURDATE() WHERE `借阅号` = 100001;
DELETE FROM l_view3 WHERE `还书日期` IS NOT NULL;