12 MySQL--內置功能介紹


mysql內置功能:
    1.視圖
    2.觸發器
    3.存儲過程
    4.事務
    5.函數
   6.函數流程控制

一、視圖

 

介紹:
     視圖是一個虛擬表(非真實存在),其本質是【根據SQL語句獲取動態的數據集,並為其命名】, 用戶使用時只需使用【名稱】即可獲取結果集,可以將該結果集當做表來使用。 使用視圖我們可以把查詢過程中的臨時表摘出來,用視圖去實現, 這樣以后再想操作該臨時表的數據時就無需重寫復雜的sql了,直接去視圖中查找即可, 但視圖有明顯地效率問題,並且視圖是存放在數據庫中的, 如果我們程序中使用的sql過分依賴數據庫中的視圖,即強耦合,那就意味着擴展sql極為不便, 因此並不推薦使用; 把sql語句查詢出來得虛擬表保存下來; 視圖:硬盤只存結構,不存數據,因為數據本身來源於其他表 減少代碼冗余,但是不建議使用,數據庫擴展,就影響視圖,就得修改視圖。 視圖得目的:取代復雜得sql語句,針對單表做視圖,沒有意義; 視圖是用來查得,多張表,視圖數據不應該被改, 視圖是方便來查得,不是用來改得!

 

 

#兩張有關系的表
mysql> select * from course;
+-----+--------+------------+
| cid | cname  | teacher_id |
+-----+--------+------------+
|   1 | 生物   |          1 |
|   2 | 物理   |          2 |
|   3 | 體育   |          3 |
|   4 | 美術   |          2 |
+-----+--------+------------+
rows in set (0.00 sec)

mysql> select * from teacher;
+-----+-----------------+
| tid | tname           |
+-----+-----------------+
|   1 | 張磊老師        |
|   2 | 李平老師        |
|   3 | 劉海燕老師      |
|   4 | 朱雲海老師      |
|   5 | 李傑老師        |
+-----+-----------------+
rows in set (0.00 sec)

#查詢李平老師教授的課程名
mysql> select cname from course where teacher_id = (select tid from teacher where tname='李平老師');
+--------+
| cname  |
+--------+
| 物理   |
| 美術   |
+--------+
rows in set (0.00 sec)

#子查詢出臨時表,作為teacher_id等判斷依據
select tid from teacher where tname='李平老師'

臨時表應用舉例

1、創建視圖

#語法:CREATE VIEW 視圖名稱 AS  SQL語句
create view teacher_view as select tid from teacher where tname='李平老師';

#於是查詢李平老師教授的課程名的sql可以改寫為
mysql> select cname from course where teacher_id = (select tid from teacher_view);
+--------+
| cname  |
+--------+
| 物理   |
| 美術   |
+--------+
rows in set (0.00 sec)

#!!!注意注意注意:
#1. 使用視圖以后就無需每次都重寫子查詢的sql,但是這么效率並不高,還不如我們寫子查詢的效率高

#2. 而且有一個致命的問題:視圖是存放到數據庫里的,如果我們程序中的sql過分依賴於數據庫中存放的視圖,
那么意味着,一旦sql需要修改且涉及到視圖的部分,則必須去數據庫中進行修改,而通常在公司中數據庫有專門的DBA負責,
你要想完成修改,必須付出大量的溝通成本DBA可能才會幫你完成修改,極其地不方便

2、使用視圖

#修改視圖,原始表也跟着改
mysql> select * from course;
+-----+--------+------------+
| cid | cname  | teacher_id |
+-----+--------+------------+
|   1 | 生物   |          1 |
|   2 | 物理   |          2 |
|   3 | 體育   |          3 |
|   4 | 美術   |          2 |
+-----+--------+------------+
rows in set (0.00 sec)

mysql> create view course_view as select * from course; #創建表course的視圖
Query OK, 0 rows affected (0.52 sec)

mysql> select * from course_view;
+-----+--------+------------+
| cid | cname  | teacher_id |
+-----+--------+------------+
|   1 | 生物   |          1 |
|   2 | 物理   |          2 |
|   3 | 體育   |          3 |
|   4 | 美術   |          2 |
+-----+--------+------------+
rows in set (0.00 sec)

mysql> update course_view set cname='xxx'; #更新視圖中的數據
Query OK, 4 rows affected (0.04 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql> insert into course_view values(5,'yyy',2); #往視圖中插入數據
Query OK, 1 row affected (0.03 sec)

mysql> select * from course; #發現原始表的記錄也跟着修改了
+-----+-------+------------+
| cid | cname | teacher_id |
+-----+-------+------------+
|   1 | xxx   |          1 |
|   2 | xxx   |          2 |
|   3 | xxx   |          3 |
|   4 | xxx   |          2 |
|   5 | yyy   |          2 |
+-----+-------+------------+
rows in set (0.00 sec)

3、修改視圖

語法:ALTER VIEW 視圖名稱 AS SQL語句
mysql> alter view teacher_view as select * from course where cid>3;
Query OK, 0 rows affected (0.04 sec)

mysql> select * from teacher_view;
+-----+-------+------------+
| cid | cname | teacher_id |
+-----+-------+------------+
|   4 | xxx   |          2 |
|   5 | yyy   |          2 |
+-----+-------+------------+
rows in set (0.00 sec)

4、刪除視圖

語法:DROP VIEW 視圖名稱

DROP VIEW teacher_view

二、 觸發器

使用觸發器可以定制用戶對表進行【增、刪、改】操作時前后的行為,注意:沒有查詢

增    before insert ;  after insert

1、創建觸發器

trigger 英 /'trɪgə/  /'trɪɡɚ/   vt 觸發、引發

 

create trigger tri_before_insert_tb1 before insert on tb1 for each row # row 行

#
插入前 觸發 CREATE TRIGGER tri_before_insert_tb1 BEFORE INSERT ON tb1 FOR EACH ROW BEGIN ... END # 插入后 CREATE TRIGGER tri_after_insert_tb1 AFTER INSERT ON tb1 FOR EACH ROW BEGIN ... END # 刪除前 CREATE TRIGGER tri_before_delete_tb1 BEFORE DELETE ON tb1 FOR EACH ROW BEGIN ... END # 刪除后 CREATE TRIGGER tri_after_delete_tb1 AFTER DELETE ON tb1 FOR EACH ROW BEGIN ... END # 更新前 CREATE TRIGGER tri_before_update_tb1 BEFORE UPDATE ON tb1 FOR EACH ROW BEGIN ... END # 更新后 CREATE TRIGGER tri_after_update_tb1 AFTER UPDATE ON tb1 FOR EACH ROW BEGIN ... END

 

delimiter英 /dɪ'lɪmɪtə/ , /dɪ'lɪmɪtɚ/ 定界符,分隔符

 

默認情況下,mysql解釋器一遇到分號(;),它就要自動執行。 不會等到用戶把這些語句全部輸入完之后,再執行整段語句。 而自定義函數和存儲過程的SQL語句有好多行,且語句中包含有分號, 為了保證整段語句的整體執行,就要使用delimiter,更改mysql的默認結束符。 

先將分隔符設置為 //, 
 
         
直到遇到下一個 //,才整體執行語句。
 
         
執行完后,最后一行, delimiter ; 將mysql的分隔符重新設置為分號;
 
         
如果不修改的話,本次會話中的所有分隔符都以// 為准。
 

 

先准備表,在創建觸發器,

#准備表
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') #0代表執行失敗
);

CREATE TABLE errlog (
    id INT PRIMARY KEY auto_increment,
    err_cmd CHAR (64),
    err_time datetime
);

#創建觸發器
delimiter //
CREATE TRIGGER tri_after_insert_cmd AFTER INSERT ON cmd FOR EACH ROW
BEGIN
    IF NEW.success = 'no' THEN #等值判斷只有一個等號 NEW是新增加進來的數據 修改old是老記錄
            INSERT INTO errlog(err_cmd, err_time) VALUES(NEW.cmd, NEW.sub_time) ; #必須加分號
      END IF ; #必須加分號
END//
delimiter ;


#往表cmd中插入記錄,觸發觸發器,根據IF的條件決定是否插入錯誤日志
INSERT INTO cmd (
    USER,
    priv,
    cmd,
    sub_time,
    success
)
VALUES
    ('egon','0755','ls -l /etc',NOW(),'yes'),
    ('egon','0755','cat /etc/passwd',NOW(),'no'),
    ('egon','0755','useradd xxx',NOW(),'no'),
    ('egon','0755','ps aux',NOW(),'yes');


#查詢錯誤日志,發現有兩條
mysql> select * from errlog;
+----+-----------------+---------------------+
| id | err_cmd         | err_time            |
+----+-----------------+---------------------+
|  1 | cat /etc/passwd | 2017-09-14 22:18:48 |
|  2 | useradd xxx     | 2017-09-14 22:18:48 |
+----+-----------------+---------------------+
rows in set (0.00 sec)

插入后觸發觸發器

 

 

特別的:NEW表示即將插入的數據行,OLD表示即將刪除的數據行。

應用開發程序員 和 數據庫程序員是兩個部分,所以實際上部分溝通問題,所以實際開發時程序員自己設計觸發器,

 

 

二 使用觸發器

 

觸發器無法由用戶直接調用,而知由於對表的【增/刪/改】操作被動引發的。

 

三 刪除觸發器

drop trigger tri_after_insert_cmd;

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM