日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

MySQL 之视图、 触发器、事务、存储过程、内置函数、流程控制、索引(一)

發布時間:2024/9/30 数据库 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 MySQL 之视图、 触发器、事务、存储过程、内置函数、流程控制、索引(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

閱讀目錄

本文內容:

  • 視圖
  • 觸發器
  • 事務
  • 存儲過程
  • 內置函數
  • 流程控制
  • 索引

一、視圖

視圖就是通過查詢得到一張虛擬表,然后保存下來,下次直接使用即可。

如果要頻繁使用一張虛擬表,可以不用重復查詢

視圖使用方法:

--------------------------------------------------------------------注:如果你對python感興趣,我這有個學習Python基地,里面有很多學習資料,感興趣的+Q群:895817687 --------------------------------------------------------------------- 將表1與表2通過on后面的條件進行內連接,產生的新表 就是我們創建的視圖表 create view 視圖表名 asselect * from1 inner join 表2on 內連接條件

具體示例:

先建基礎數據表及其記錄(由于博客園暫找不到上傳文件的地方,所以只能插入創建表的sql語句,將其復制粘貼到txt文檔里面,最好是notpad++里面,然后存為sql文件,在Navicat里面導入就行了)

View Code

/*Navicat Premium Data TransferSource Server : sgt'mysqlSource Server Type : MySQLSource Server Version : 50726Source Host : localhost:3306Source Schema : day41Target Server Type : MySQLTarget Server Version : 50726File Encoding : 65001Date: 17/05/2019 14:54:11 */SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0;-- ---------------------------- -- Table structure for class -- ---------------------------- DROP TABLE IF EXISTS `class`; CREATE TABLE `class` (`cid` int(11) NOT NULL AUTO_INCREMENT,`caption` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (`cid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of class -- ---------------------------- INSERT INTO `class` VALUES (1, '三年二班'); INSERT INTO `class` VALUES (2, '三年三班'); INSERT INTO `class` VALUES (3, '一年二班'); INSERT INTO `class` VALUES (4, '二年九班');-- ---------------------------- -- Table structure for course -- ---------------------------- DROP TABLE IF EXISTS `course`; CREATE TABLE `course` (`cid` int(11) NOT NULL AUTO_INCREMENT,`cname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`teacher_id` int(11) NOT NULL,PRIMARY KEY (`cid`) USING BTREE,INDEX `fk_course_teacher`(`teacher_id`) USING BTREE,CONSTRAINT `fk_course_teacher` FOREIGN KEY (`teacher_id`) REFERENCES `teacher` (`tid`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of course -- ---------------------------- INSERT INTO `course` VALUES (1, '生物', 1); INSERT INTO `course` VALUES (2, '物理', 2); INSERT INTO `course` VALUES (3, '體育', 3); INSERT INTO `course` VALUES (4, '美術', 2);-- ---------------------------- -- Table structure for score -- ---------------------------- DROP TABLE IF EXISTS `score`; CREATE TABLE `score` (`sid` int(11) NOT NULL AUTO_INCREMENT,`student_id` int(11) NOT NULL,`course_id` int(11) NOT NULL,`num` int(11) NOT NULL,PRIMARY KEY (`sid`) USING BTREE,INDEX `fk_score_student`(`student_id`) USING BTREE,INDEX `fk_score_course`(`course_id`) USING BTREE,CONSTRAINT `fk_score_course` FOREIGN KEY (`course_id`) REFERENCES `course` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT,CONSTRAINT `fk_score_student` FOREIGN KEY (`student_id`) REFERENCES `student` (`sid`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 53 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of score -- ---------------------------- INSERT INTO `score` VALUES (1, 1, 1, 10); INSERT INTO `score` VALUES (2, 1, 2, 9); INSERT INTO `score` VALUES (5, 1, 4, 66); INSERT INTO `score` VALUES (6, 2, 1, 8); INSERT INTO `score` VALUES (8, 2, 3, 68); INSERT INTO `score` VALUES (9, 2, 4, 99); INSERT INTO `score` VALUES (10, 3, 1, 77); INSERT INTO `score` VALUES (11, 3, 2, 66); INSERT INTO `score` VALUES (12, 3, 3, 87); INSERT INTO `score` VALUES (13, 3, 4, 99); INSERT INTO `score` VALUES (14, 4, 1, 79); INSERT INTO `score` VALUES (15, 4, 2, 11); INSERT INTO `score` VALUES (16, 4, 3, 67); INSERT INTO `score` VALUES (17, 4, 4, 100); INSERT INTO `score` VALUES (18, 5, 1, 79); INSERT INTO `score` VALUES (19, 5, 2, 11); INSERT INTO `score` VALUES (20, 5, 3, 67); INSERT INTO `score` VALUES (21, 5, 4, 100); INSERT INTO `score` VALUES (22, 6, 1, 9); INSERT INTO `score` VALUES (23, 6, 2, 100); INSERT INTO `score` VALUES (24, 6, 3, 67); INSERT INTO `score` VALUES (25, 6, 4, 100); INSERT INTO `score` VALUES (26, 7, 1, 9); INSERT INTO `score` VALUES (27, 7, 2, 100); INSERT INTO `score` VALUES (28, 7, 3, 67); INSERT INTO `score` VALUES (29, 7, 4, 88); INSERT INTO `score` VALUES (30, 8, 1, 9); INSERT INTO `score` VALUES (31, 8, 2, 100); INSERT INTO `score` VALUES (32, 8, 3, 67); INSERT INTO `score` VALUES (33, 8, 4, 88); INSERT INTO `score` VALUES (34, 9, 1, 91); INSERT INTO `score` VALUES (35, 9, 2, 88); INSERT INTO `score` VALUES (36, 9, 3, 67); INSERT INTO `score` VALUES (37, 9, 4, 22); INSERT INTO `score` VALUES (38, 10, 1, 90); INSERT INTO `score` VALUES (39, 10, 2, 77); INSERT INTO `score` VALUES (40, 10, 3, 43); INSERT INTO `score` VALUES (41, 10, 4, 87); INSERT INTO `score` VALUES (42, 11, 1, 90); INSERT INTO `score` VALUES (43, 11, 2, 77); INSERT INTO `score` VALUES (44, 11, 3, 43); INSERT INTO `score` VALUES (45, 11, 4, 87); INSERT INTO `score` VALUES (46, 12, 1, 90); INSERT INTO `score` VALUES (47, 12, 2, 77); INSERT INTO `score` VALUES (48, 12, 3, 43); INSERT INTO `score` VALUES (49, 12, 4, 87); INSERT INTO `score` VALUES (52, 13, 3, 87);-- ---------------------------- -- Table structure for student -- ---------------------------- DROP TABLE IF EXISTS `student`; CREATE TABLE `student` (`sid` int(11) NOT NULL AUTO_INCREMENT,`gender` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,`class_id` int(11) NOT NULL,`sname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (`sid`) USING BTREE,INDEX `fk_class`(`class_id`) USING BTREE,CONSTRAINT `fk_class` FOREIGN KEY (`class_id`) REFERENCES `class` (`cid`) ON DELETE RESTRICT ON UPDATE RESTRICT ) ENGINE = InnoDB AUTO_INCREMENT = 17 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of student -- ---------------------------- INSERT INTO `student` VALUES (1, '男', 1, '理解'); INSERT INTO `student` VALUES (2, '女', 1, '鋼蛋'); INSERT INTO `student` VALUES (3, '男', 1, '張三'); INSERT INTO `student` VALUES (4, '男', 1, '張一'); INSERT INTO `student` VALUES (5, '女', 1, '張二'); INSERT INTO `student` VALUES (6, '男', 1, '張四'); INSERT INTO `student` VALUES (7, '女', 2, '鐵錘'); INSERT INTO `student` VALUES (8, '男', 2, '李三'); INSERT INTO `student` VALUES (9, '男', 2, '李一'); INSERT INTO `student` VALUES (10, '女', 2, '李二'); INSERT INTO `student` VALUES (11, '男', 2, '李四'); INSERT INTO `student` VALUES (12, '女', 3, '如花'); INSERT INTO `student` VALUES (13, '男', 3, '劉三'); INSERT INTO `student` VALUES (14, '男', 3, '劉一'); INSERT INTO `student` VALUES (15, '女', 3, '劉二'); INSERT INTO `student` VALUES (16, '男', 3, '劉四');-- ---------------------------- -- Table structure for teacher -- ---------------------------- DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` (`tid` int(11) NOT NULL AUTO_INCREMENT,`tname` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,PRIMARY KEY (`tid`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;-- ---------------------------- -- Records of teacher -- ---------------------------- INSERT INTO `teacher` VALUES (1, '張磊老師'); INSERT INTO `teacher` VALUES (2, '李平老師'); INSERT INTO `teacher` VALUES (3, '劉海燕老師'); INSERT INTO `teacher` VALUES (4, '朱云海老師'); INSERT INTO `teacher` VALUES (5, '李杰老師');-- ---------------------------- -- View structure for teacher2course -- ---------------------------- DROP VIEW IF EXISTS `teacher2course`; CREATE ALGORITHM = UNDEFINED SQL SECURITY DEFINER VIEW `teacher2course` AS select `teacher`.`tid` AS `tid`,`teacher`.`tname` AS `tname`,`course`.`cid` AS `cid`,`course`.`cname` AS `cname`,`course`.`teacher_id` AS `teacher_id` from (`teacher` join `course` on((`teacher`.`tid` = `course`.`teacher_id`)));SET FOREIGN_KEY_CHECKS = 1; -- 創建視圖 create view teacher2course as select * from teacher inner join course on teacher.tid=course.teacher_id-- 查看創建的視圖 select * from teacher2course tid tname cid cname teacher_id 1 張磊老師 1 生物 1 2 李平老師 2 物理 2 3 劉海燕老師 3 體育 3 2 李平老師 4 美術 2

這里需要強調幾點:

  • 在硬盤中,視圖只有表結構文件,沒有表數據文件
  • 視圖通常是用于查詢,盡量不要修改視圖中的數據
  • 刪除視圖代碼:drop view teacher2course

思考:真實開發過程中是否會使用視圖?
我們已經說過,視圖是mysql的功能,這個功能主要用于查詢,但是如果一個項目中使用了很多視圖,那么如果項目某個功能需要修改的時候,就會需要對視圖進行修改,這時候就需要在mysql端將視圖進行修改,然后再去應用程序修改對應的sql語句,其實這就會導致一個跨部門溝通問題,部門與部門溝通并不是不可以,但是我們應該在軟件代碼層面上盡量減少這么溝通次數,因為一方面人與人之間的交往問題,另一方面也是項目擴展高效性的一方面考慮。一般程序擴展功能都是通過修改sql語句來完成的。(以上僅個人意見,歡迎交流)

二、觸發器

  • 定義:當對某張表的記錄進行增、刪、改的行為下,會滿足這一行為條件后自動觸發某一設定功能稱之為觸發器。
  • 目的:觸發器主要是專門針對我們隊某一張表記錄進行新增insert、刪delete、改update的行為,這類行為一旦執行,就會滿足觸發器觸發條件,即自動運行觸發器設定的另一段sql語句。
  • 如何創建觸發器:
-- 針對插入時觸發sql代碼... create trigger tri_after_insert_t1 after insert on 表名 for each row -- 插入后觸發 BEGINsql代碼... ENDcreate trigger tri_before_insert_t2 before insert on 表名 for each row -- 插入前觸發 BEGINsql代碼... END -- ------------------------------------------------------------------------------ -- 針對刪除時觸發sql代碼... create trigger 觸發器名 after delete on 表名 for each row -- 刪除后觸發 BEGINsql代碼... ENDcreate trigger 觸發器名 before delete on 表名 for each row -- 刪除前觸發 BEGINsql代碼... END -- ------------------------------------------------------------------------------ -- 針對修改時觸發sql代碼... create trigger 觸發器名 after update on 表名 for each row -- 修改后觸發 BEGINsql代碼... ENDcreate trigger 觸發器名 before update on 表名 for each row -- 修改前觸發 BEGINsql代碼... END以上觸發器的創建代碼格式比較固定,只是分了6種情況而已
  • 下面通過一個案例來進一步認識觸發器:
-- 創建2張表 create table cmd(id int primary key auto_increment,user char(32),priv char(10),cmd char(64),sub_time datetime,success enum('yes','no'));create table errlog(id int primary key auto_increment,err_cmd char(64),err_time datetime);-- 創建觸發器 delimiter // -- 將mysql默認的結束符換成// create trigger tri_after_insert_cmd after insert on cmd for each row beginif NEW.success='no' then -- 用NEW代表mysql捕獲并封裝成的新紀錄對象insert into errlog(err_cmd,err_time) values (NEW.cmd,NEW.sub_time);end if; -- if語句結束語 end // -- 前面講結束符改為//。這里寫上//代表觸發器創建完畢,結束 delimiter ; -- 結束后記得將結束符改回默認;-- 插入數據; insert into cmd(user,priv,cmd,sub_time,success) values('王大錘','0755','ls -l /etc',NOW(),'yes'), -- NOW()代表獲取當前時間('孫大炮','0755','cat /etc/passwd',NOW(),'no'),('李大大','0755','useradd xxx',NOW(),'no'),('趙州橋','0755','ps aux',NOW(),'yes'); -- 向cmd表插入數據時候,觸發器觸發,會根據觸發器內if條件語句判斷是否決定插入錯誤日志-- 查詢errlog表記錄,看看是否觸發了觸發器 select * from errlog; -- 結果: -- id err_cmd err_time -- 1 cat /etc/passwd 2019-05-17 16:03:23 -- 2 useradd xxx 2019-05-17 16:03:23 -- 刪除觸發器 drop trigger tri_after_insert_cmd;

三、事務

  • 簡言之:多個sql語句執行生效的狀態必須同步進行
    也就是說開啟事務后,事務里的所有sql語句,要么全部生效成功,只要有一個失敗,就全部不生效不成功。(應用場景可以想象銀行轉賬,雙方必須都完成應該有的過程才能算轉賬成功,否則轉賬不成功。)
  • 作用:保證事務內數據處理的同步性,讓數據操作更具安全性。
  • 事務四大屬性:(需要重點記憶)
  • 原子性:一個事務是不可分割的集合,其中包括的操作必須都成功,否則視為不成功

  • 一致性:事務必須是使數據庫從一個一致性狀態變到另一個一致性狀態,與原子性密切相關的

  • 隔離性:多個事務直接互不干擾,也就是說事務內數據操作與另一事務內的數據操作是相互隔離的,并發執行的各個事務之間互不干擾。

  • 4.持久性:永久性,事務如果提交,對數據庫的改變是永久性的,接下來的其他操作貨故障不會對其有任何影響。

    • 使用實例:
    create table user(id int primary key auto_increment,name char(32),balance int);insert into user(name,balance) values('李逍遙',1000),('酒劍仙',1000),('趙靈兒',1000);-- 修改數據之前開啟事務操作:start transaction;-- 修改操作update user set balance=900 where id=1;-- 買支付100元update user set balance=900 where id=2;-- 中介拿走10元update user set balance=900 where id=3;-- 賣家拿到90-- 查看修改后的表: select * from user; -- 結果 -- id name balance -- 1 李逍遙 900 -- 2 酒劍仙 900 -- 3 趙靈兒 900 -- 注意注意 -- 事務下的sql語句執行完畢后并沒有最終對數據庫數據產生實質性改變,如果要 -- 產生最終結果生效,也就是數據真正地刷新到硬盤,就必須要執行一段提交的語句 -- 在執行提交語句前,進行的修改還可以還原,也就是sql回滾語句 rollback; -- 再查看表: select * from user; -- 結果(數據還原了) -- id name balance -- 1 李逍遙 1000 -- 2 酒劍仙 1000 -- 3 趙靈兒 1000 -- 再次執行修改操作并提交: -- 修改操作update user set balance=900 where id=1;-- 買支付100元update user set balance=900 where id=2;-- 中介拿走10元update user set balance=900 where id=3;-- 賣家拿到90元 commit; select * from user; -- 結果 -- id name balance -- 1 李逍遙 900 -- 2 酒劍仙 900 -- 3 趙靈兒 900-- 思考: -- 如果站在python代碼的角度,該如何實現檢測事務內操作的全部成功性,不成功就回滾到前一個狀態: update user set balance=900 where id=1;-- 買支付100元 update user set balance=900 where id=2;-- 中介拿走10元 update user set balance=900 where id=3;-- 賣家拿到90if 檢測到三方的余額都發生應該有的變化:commint; else:rollblack;

    四、存儲過程

  • 簡言之:將一些列的可執行的sql語句,封裝為一個存儲過程,存放于MySQL中,通過調用他的名字就可以執行其內部的一堆sql語句的目的。
  • 在認識存儲過程之前我們需要先了解下三種開發模型:
  • 應用程序:只需要開發應用程序的邏輯 mysql:編寫好存儲過程,以供應用程序調用
    優點:開發效率高,執行效率高(因為我只需要負責應用程序邏輯層的問題,數據庫層的有人幫我封裝好了存儲過程,我直接調用就行。)
    缺點:將開發應用分為2個部門,如果涉及到擴展情況,相關的存儲過程需要修改的話,就需要與數據庫部門產生溝通過程,考慮到人為因素,跨部門溝通等問題,綜合性來說會導致擴展性變差。
  • 應用程序:兩方面都會,既會開發應用程序的邏輯,又會寫sql,寫存儲過程。 優點:比上一種方式在擴展性方面(非技術性上)更高
    缺點:開發效率和執行效率都不方第一種模型低,因為一個人2個方面的事都他干了,開發效率和執行效率能高嗎!同時考慮到編寫sql語句的復雜性,同時也要考慮到sql語句的優化問題,這些都涉及到術業有專攻的問題,最終還是會導致開發效率低的問題。
  • 應用程序:開發應用程序的邏輯,不需要寫sql,而是基于別人編寫好的框架來處理處理數據,ORM 。
    優點:不用像模型2那樣編寫sql,開發效率肯定比模型2高,同時兼容了2的擴展性高得好處 缺點:執行效率上面比較低,比2低。
  • 創建存儲過程:

    delimiter // create procedure p1(in m int, -- in表示這個參數必須只能是傳入不能被返回出去in n int,out res int) -- out表示這個參數可以被返回出去,還有一個inout表示傳入傳出可返回出去beginselect tname from teacher where tid > m and tid < n;set res = 0; end // delimiter ;
    • 使用存儲過程:
    -- 直接在mysql中調用:delimiter // create procedure p1(in m int, -- in表示這個參數必須只能是傳入不能被返回出去in n int,out res int) -- out表示這個參數可以被返回出去,還有一個inout表示傳入傳出可返回出去beginselect tname from teacher where tid > m and tid < n;set res = 0; end // delimiter ;-- 需要注意:存儲過程在哪個數據庫下創建的就必須只能在對應的數據庫下面使用 -- 直接在mysql中調用 set @res=8 -- res是判斷存儲過程是否被執行成功的依據,在這里需要先定義一個變量@res=8 -- call p1(2,4,8); -- 如果直接傳8則報錯,必須傳事先定義的變量@res,這是規定語法規范 call p1(2,4,@res); -- tname -- 劉海燕老師 --查看結果 select @res; -- res=0 -- 存儲過程被調用,@res變量值發生變化 -- 在python程序中調用:import pymysql conn = pymysql.connect(host='127.0.0.1',port=3306,user='root',password='sgtkey',database='day41',charset='utf8' ) cursor = conn.cursor(cursor=pymysql.cursors.DictCursor) cursor.callproc('p1', (2, 4, 8)) # 這里就不需要提前定義個變量@res了,pymsql自動給你做了這件事 # 這里的內部原理:@_p1_0=2,@_p1_1=4,@_p1_2=8; print(cursor.fetchall()) # 結果 [{'tname': '劉海燕老師'}] cursor.execute('select @_p1_2') print(cursor.fetchall()) # 結果 [{'@_p1_2': 0}]

    未完待續

    總結

    以上是生活随笔為你收集整理的MySQL 之视图、 触发器、事务、存储过程、内置函数、流程控制、索引(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。