1. 概念及作用
1.1 概念
视图,就是 由数据库中⼀张表或多张表 根据特定条件查询出来的数据
所构造成的一张 虚拟表
。
1.2 作用安全性
:如果我们直接将数据表授权给⽤户操作,那么⽤户可以CRUD数据表中所有数据
,假如我们想要对数据表中的部分数据进⾏保护,可以将公开的数据⽣成视图,授权⽤户访问视图;⽤户通过查询视图可以获取数据表中公开的数据,从⽽达到将数据表中的部分数据对⽤户隐藏
。简单性
:如果我们需要查询的数据来源于多张数据表,可以使⽤多表连接查询来实现;我们通过视图将这些多表连接查询的结果对⽤户开放,⽤户则可以直接通过查询视图获取多表数据,操作更便捷。
2. 创建视图
2.0
数据源
/*
Navicat Premium Data Transfer
Source Server : localhost_3306
Source Server Type : MySQL
Source Server Version : 80016
Source Host : localhost:3306
Source Schema : book_db
Target Server Type : MySQL
Target Server Version : 80016
File Encoding : 65001
Date: 23/05/2023 00:00:23
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for books
-- ----------------------------
DROP TABLE IF EXISTS `books`;
CREATE TABLE `books` (
`book_id` int(11) NOT NULL AUTO_INCREMENT,
`book_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`book_author` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`book_price` decimal(10, 2) NOT NULL,
`book_stock` int(11) NOT NULL,
`book_desc` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`book_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of books
-- ----------------------------
INSERT INTO `books` VALUES (1, 'Java无难事', '孙鑫', 38.80, 7, '零基础讲解java');
INSERT INTO `books` VALUES (2, 'linux就该这么学', '鸟哥', 44.40, 2, '跟我从零开始学linux');
-- ----------------------------
-- Table structure for records
-- ----------------------------
DROP TABLE IF EXISTS `records`;
CREATE TABLE `records` (
`rid` int(11) NOT NULL AUTO_INCREMENT,
`snum` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`bid` int(11) NOT NULL,
`borrow_num` int(11) NOT NULL,
`is_return` int(11) NOT NULL,
`borrow_date` date NOT NULL,
PRIMARY KEY (`rid`) USING BTREE,
INDEX `FK_RECORDS_STUDENTS`(`snum`) USING BTREE,
INDEX `FK_RECORDS_BOOKS`(`bid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of records
-- ----------------------------
INSERT INTO `records` VALUES (2, '1001', 1, 2, 0, '2023-05-21');
INSERT INTO `records` VALUES (6, '1002', 1, 1, 0, '2023-05-22');
INSERT INTO `records` VALUES (7, '1003', 2, 3, 0, '2023-05-22');
-- ----------------------------
-- Table structure for students
-- ----------------------------
DROP TABLE IF EXISTS `students`;
CREATE TABLE `students` (
`stu_num` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`stu_name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`stu_gender` char(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
`stu_age` int(11) NOT NULL,
PRIMARY KEY (`stu_num`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of students
-- ----------------------------
INSERT INTO `students` VALUES ('1001', '张三三', '男', 20);
INSERT INTO `students` VALUES ('1002', '李四', '男', 20);
INSERT INTO `students` VALUES ('1003', '王五五', '女', 20);
INSERT INTO `students` VALUES ('1111', '高俅', '男', 45);
-- ----------------------------
-- Table structure for stulogs
-- ----------------------------
DROP TABLE IF EXISTS `stulogs`;
CREATE TABLE `stulogs` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time` timestamp(0) NULL DEFAULT NULL,
`log_text` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of stulogs
-- ----------------------------
INSERT INTO `stulogs` VALUES (4, '2023-05-22 22:08:23', '添加1005学生信息');
INSERT INTO `stulogs` VALUES (5, '2023-05-22 22:08:23', '添加1006学生信息');
INSERT INTO `stulogs` VALUES (6, '2023-05-22 22:14:13', '修改学生信息为1006赵八ba');
INSERT INTO `stulogs` VALUES (7, '2023-05-22 22:21:41', '删除1005学生信息');
INSERT INTO `stulogs` VALUES (18, '2023-05-22 22:32:25', '修改学生信息为1003王五五');
INSERT INTO `stulogs` VALUES (19, '2023-05-22 22:32:25', '将学生姓名从 王五 修改为王五五');
INSERT INTO `stulogs` VALUES (20, '2023-05-22 22:49:40', '修改学生信息为1003王五五');
INSERT INTO `stulogs` VALUES (21, '2023-05-22 22:49:40', '将学生姓名从 王五五 修改为王五五');
INSERT INTO `stulogs` VALUES (22, '2023-05-22 23:37:01', '添加1111学生信息');
INSERT INTO `stulogs` VALUES (23, '2023-05-22 23:37:45', '修改学生信息为1001张三三');
INSERT INTO `stulogs` VALUES (24, '2023-05-22 23:37:45', '将学生姓名从 张三 修改为张三三');
INSERT INTO `stulogs` VALUES (25, '2023-05-22 23:47:34', '删除1111学生信息');
INSERT INTO `stulogs` VALUES (26, '2023-05-22 23:47:36', '修改学生信息为1001张三');
INSERT INTO `stulogs` VALUES (27, '2023-05-22 23:47:36', '将学生姓名从 张三三 修改为张三');
INSERT INTO `stulogs` VALUES (28, '2023-05-22 23:48:00', '添加1111学生信息');
INSERT INTO `stulogs` VALUES (29, '2023-05-22 23:49:47', '修改学生信息为1001张三三');
INSERT INTO `stulogs` VALUES (30, '2023-05-22 23:49:47', '将学生姓名从 张三 修改为张三三');
-- ----------------------------
-- Table structure for temp
-- ----------------------------
DROP TABLE IF EXISTS `temp`;
CREATE TABLE `temp` (
`num` int(11) NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of temp
-- ----------------------------
INSERT INTO `temp` VALUES (102);
INSERT INTO `temp` VALUES (103);
INSERT INTO `temp` VALUES (104);
-- ----------------------------
-- View structure for view_test1
-- ----------------------------
DROP VIEW IF EXISTS `view_test1`;
CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `view_test1` AS select `students`.`stu_num` AS `stu_num`,`students`.`stu_name` AS `stu_name`,`students`.`stu_gender` AS `stu_gender`,`students`.`stu_age` AS `stu_age` from `students` where (`students`.`stu_gender` = '男');
-- ----------------------------
-- View structure for view_test2
-- ----------------------------
DROP VIEW IF EXISTS `view_test2`;
CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `view_test2` AS select `s`.`stu_name` AS `stu_name`,`b`.`book_name` AS `book_name`,`r`.`borrow_num` AS `borrow_num` from ((`books` `b` join `records` `r`) join `students` `s` on(((`b`.`book_id` = `r`.`bid`) and (`r`.`snum` = `s`.`stu_num`))));
-- ----------------------------
-- Procedure structure for proc_borrow_book
-- ----------------------------
DROP PROCEDURE IF EXISTS `proc_borrow_book`;
delimiter ;;
CREATE PROCEDURE `proc_borrow_book`(IN a char(4), IN b int, IN m int, OUT state int)
begin
declare stu_count int default 0;
declare book_count int default 0;
declare stock int default 0;
-- 判断学号是否存在:根据参数 a 到学⽣信息表查询是否有stu_num=a的记录
select count(stu_num) INTO stu_count from students where stu_num=a;
if stu_count>0 then
-- 学号存在
-- 判断图书ID是否存在:根据参数b 查询图书记录总数
select count(book_id) INTO book_count from books where book_id=b;
if book_count >0 then
-- 图书存在
-- 判断图书库存是否充足?查询当前图书库存,然后和参数m进行比较
select book_stock INTO stock from books where book_id=b;
if stock >= m then
-- 执行借书
-- 操作1:在借书记录表中添加记录
insert into records(snum,bid,borrow_num,is_return,borrow_date) values(a,b,m,0,sysdate());
-- 操作2:修改图书库存
update books set book_stock=stock-m where book_id=b;
-- 借书成功
set state=1;
else
-- 库存不足
set state=4;
end if;
else
-- 图书不存在
set state = 3;
end if;
else
-- 不存在
set state = 2;
end if;
end
;;
delimiter ;
-- ----------------------------
-- Function structure for test_fun1
-- ----------------------------
DROP FUNCTION IF EXISTS `test_fun1`;
delimiter ;;
CREATE FUNCTION `test_fun1`(id int)
RETURNS varchar(100) CHARSET utf8mb4
READS SQL DATA
begin
declare name varchar(20);
select book_name INTO name from books where book_id=id;
return name;
end
;;
delimiter ;
-- ----------------------------
-- Procedure structure for use_cursor
-- ----------------------------
DROP PROCEDURE IF EXISTS `use_cursor`;
delimiter ;;
CREATE PROCEDURE `use_cursor`(OUT res varchar(100))
begin
declare bname varchar(20);
declare bauthor varchar(20);
declare bprice decimal(10, 2);
declare count int default 0;
declare i int default 0;
declare string varchar(100);
declare MyCursor cursor for select book_name, book_author, book_price from books;
select count(1) INTO count from books;
open MyCursor;
while i < count do
fetch MyCursor INTO bname, bauthor, bprice;
set i = i + 1;
-- set string = CONCAT_WS('#', bname, bauthor, bprice);
select CONCAT_WS('#', bname, bauthor, bprice) INTO string;
set res = CONCAT_WS(',', res, string);
end while;
close MyCursor;
end
;;
delimiter ;
-- ----------------------------
-- Triggers structure for table students
-- ----------------------------
DROP TRIGGER IF EXISTS `trigger_test4`;
delimiter ;;
CREATE TRIGGER `trigger_test4` AFTER UPDATE ON `students` FOR EACH ROW insert into stulogs(time, log_text) values(now(), concat('将学生姓名从 ', OLD.stu_name, ' 修改为', NEW.stu_name))
;;
delimiter ;
-- ----------------------------
-- Triggers structure for table students
-- ----------------------------
DROP TRIGGER IF EXISTS `trigger_test1`;
delimiter ;;
CREATE TRIGGER `trigger_test1` AFTER INSERT ON `students` FOR EACH ROW insert into stulogs(time, log_text) values(now(), concat('添加', NEW.stu_num,'学生信息'))
;;
delimiter ;
-- ----------------------------
-- Triggers structure for table students
-- ----------------------------
DROP TRIGGER IF EXISTS `trigger_test2`;
delimiter ;;
CREATE TRIGGER `trigger_test2` AFTER UPDATE ON `students` FOR EACH ROW insert into stulogs(time, log_text) values(now(), concat('修改学生信息为', NEW.stu_num,NEW.stu_name))
;;
delimiter ;
-- ----------------------------
-- Triggers structure for table students
-- ----------------------------
DROP TRIGGER IF EXISTS `trigger_test3`;
delimiter ;;
CREATE TRIGGER `trigger_test3` AFTER DELETE ON `students` FOR EACH ROW insert into stulogs(time, log_text) values(now(), concat('删除', OLD.stu_num, '学生信息'))
;;
delimiter ;
SET FOREIGN_KEY_CHECKS = 1;
2.1
语法及实例
-- 语法格式
create view 视图名
as
select_statement
-- 创建视图实例1:将学⽣表中性别为男的学⽣⽣成⼀个视图
create view view_test1
as
select * from students where stu_gender='男';
select * from view_test1;
-- 创建视图示例2:查询学⽣借书的信息(学⽣名、图书名、借书数量)
create VIEW view_test2
AS
SELECT s.stu_name, b.book_name, r.borrow_num FROM books AS b INNER JOIN records AS r INNER JOIN students AS s
ON b.book_id=r.bid AND r.snum=s.stu_num;
SELECT * FROM view_test2;
3. 视图特性
视图是虚拟表,查询视图的数据是来源于数据表的。当对视图进⾏操作时,对原数据表中的数据是否由影响呢???
(1)
查询操作:如果在数据表中添加了新的数据,同时这个数据满⾜创建视图时查询语句的条件,通过查询视图也可以查询出新增的数据;当删除原表中满⾜查询条件的数据时,也会从视图中删除;(2)
新增数据: 如果在视图中添加数据,数据会被添加到原数据表;(3)
删除数据: 如果从视图删除数据,数据也将从原表中删除;(4)
修改操作: 如果通过修改数据,则也将修改原数据表中的数据。
视图的使⽤建议 : 对复杂查询简化操作,并且不会对数据进⾏修改的情况下可以使⽤视图
。
-- 在视图中插入数据
insert into view_test1 values('1111', '高俅', '男', 45);
select * from view_test1;
select * from students;
-- 修改视图中的数据
update view_test1 set stu_name='张三三' where stu_name='张三';
select * from view_test1;
select * from students;
-- 删除视图中的数据
create view view_test3 as select * from temp;
delete from view_test3 where num=101;
select * from view_test3;
select * from temp;
4. 查询视图结构
desc view_test1;
5. 修改视图
5.1
方式1(OR REPLACE
)
-- 修改视图view_test1中的查询语句中的条件为女
create OR REPLACE view view_test1
as
select * from students where stu_gender='女';
5.2
方式2(alter
)
alter view view_test1
as
select * from students where stu_gender='男';
6. 删除视图
删除数据表时会同时删除数据表中的数据,删除视图时不会影响原数据表中的数据。
drop view view_test3;