1. 程式人生 > 其它 >Mysql_檢視及事務等_劉益長

Mysql_檢視及事務等_劉益長

一、檢視

1.1、什麼是檢視?

檢視(view)是一種虛擬存在的表,是一個邏輯表,本身並不包含資料。作為一個select語句儲存在資料字典中的。

1.2、檢視是幹什麼用的?

通過檢視,可以展現基表的部分資料; 檢視資料來自定義檢視的查詢中使用的表,使用檢視動態生成。 基表:用來建立檢視的表叫做基表

1.3、為什麼要使用檢視?

因為檢視的諸多優點,如下

1)簡單:使用檢視的使用者完全不需要關心後面對應的表的結構、關聯條件和篩選條件,對使用者來說已經是過濾好的複合條件的結果集。

2)安全:使用檢視的使用者只能訪問他們被允許查詢的結果集,對錶的許可權管理並不能限制到某個行某個列,但是通過檢視就可以簡單的實現。

3)資料獨立:一旦檢視的結構確定了,可以遮蔽表結構變化對使用者的影響,源表增加列對檢視沒有影響;源表修改列名,則可以通過修改檢視來解決,不會造成對訪問者的影響。

總而言之,使用檢視的大部分情況是為了保障資料安全性,提高查詢效率。

2、因為檢視是需要基表才能構建,因此在講解檢視的時候,我們需要先建立兩張資料表用於後面演示檢視操作,下面是測試表和測試資料建立的SQL語句。

2.1、建立部落格表和作者表

CREATE DATABASE IF NOT EXISTS info DEFAULT CHARSET utf8;
USE info;
#建立作者表
CREATE TABLE IF NOT EXISTS
author( id INT NOT NULL AUTO_INCREMENT, author_name VARCHAR(50) DEFAULT NULL, PRIMARY KEY(id) ); INSERT INTO author(author_name)VALUES('naamman'), ('lucy'),('lily'),('jack'); #建立部落格表 CREATE TABLE IF NOT EXISTS blog( id INT PRIMARY KEY AUTO_INCREMENT, title VARCHAR(50) DEFAULT NULL, content VARCHAR(100) DEFAULT
NULL, author_id INT DEFAULT NULL ); INSERT INTO blog(title,content,author_id)VALUES ('測試部落格01','部落格內容01',1), ('測試部落格02','部落格內容02',2), ('測試部落格03','部落格內容03',3), ('測試部落格04','部落格內容04',4);

2.2、建立檢視

#建立檢視:邏輯上的虛擬表
CREATE VIEW v_author(編號,姓名)
AS
SELECT * FROM author WITH CHECK OPTION;

#查詢檢視
SELECT * FROM v_author;

建立多表檢視

#建立多表檢視(自己寫)
CREATE VIEW v_a_b(作者名字,部落格標題,部落格內容)
AS
SELECT a.author_name,b.title,b.content FROM author a LEFT JOIN blog b ON a.id=b.author_id;
SELECT * FROM v_a_b;

2.3、修改檢視

#修改檢視:沒有就建立,有就替換
CREATE OR REPLACE VIEW v_blog(編號,標題,內容,作者編號)
AS SELECT * FROM blog
WITH CHECK OPTION;

#修改檢視的資料->修改基表資料
UPDATE v_blog SET 內容 = '修改後的內容' WHERE 編號 = 1;
SELECT * FROM v_blog

2.4、with check option:where條件約束

#部分資料建立檢視
CREATE OR REPLACE VIEW v_blog_1(編號,標題,內容,作者編號)
AS SELECT * FROM blog WHERE author_id=1
WITH CHECK OPTION;

--with check option:where條件約束
INSERT INTO v_blog_1(標題,內容,作者編號)VALUES('123','123',1);
UPDATE v_blog_1 SET 內容 = '部落格內容05' WHERE 編號 = 5;
SELECT * FROM v_blog_1;

二、事務

2.1、什麼是事務

事務就是使用者定義的一系列執行SQL語句的操作, 這些操作要麼完全地執行,要麼完全地都不執行, 它是一個不可分割的工作執行單元。
事務的使用場景:
在日常生活中,有時我們需要進行銀行轉賬,這個銀行轉賬操作背後就是需要執行多個SQL語句,假
如這些SQL執行到一半突然停電了,那麼就會導致這個功能只完成了一半,這種情況是不允許出現,
要想解決這個問題就需要通過事務來完成。

2.2、四大特點

原子性:一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。

一致性:在事務開始之前和事務結束以後,資料庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續資料庫可以自發性地完成預定的工作。

隔離性:資料庫允許多個併發事務同時對其資料進行讀寫和修改的能力,隔離性可以防止多個事務併發執行時由於交叉執行而導致資料的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重複讀(repeatable read)和序列化(Serializable)。

永續性:事務處理結束後,對資料的修改就是永久的,即便系統故障也不會丟失。

2.3、事務控制語句

BEGIN 或 START TRANSACTION 顯式地開啟一個事務;

COMMIT 也可以使用 COMMIT WORK,不過二者是等價的。COMMIT 會提交事務,並使已對資料庫進行的所有修改成為永久性的;

ROLLBACK 也可以使用 ROLLBACK WORK,不過二者是等價的。回滾會結束使用者的事務,並撤銷正在進行的所有未提交的修改;

SAVEPOINT identifier,SAVEPOINT 允許在事務中建立一個儲存點,一個事務中可以有多個 SAVEPOINT;

RELEASE SAVEPOINT identifier 刪除一個事務的儲存點,當沒有指定的儲存點時,執行該語句會丟擲一個異常;

ROLLBACK TO identifier 把事務回滾到標記點;

SET TRANSACTION 用來設定事務的隔離級別。

InnoDB 儲存引擎提供事務的隔離級別有READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

2.4、MYSQL 事務處理主要有兩種方法:

1、用 BEGIN, ROLLBACK, COMMIT來實現 BEGIN 開始一個事務 ROLLBACK 事務回滾 COMMIT 事務確認

CREATE TABLE runoob_transaction_test(id INT(5));

# 開啟事務
BEGIN;
# 插入資料
INSERT INTO runoob_transaction_test VALUES(1);
INSERT INTO runoob_transaction_test VALUES(2);
# 提交事務
COMMIT;

# 開啟事務
BEGIN;
# 插入資料
INSERT INTO runoob_transaction_test VALUES("aaa");
INSERT INTO runoob_transaction_test VALUES(4);
# 事務回滾
ROLLBACK;

SELECT * FROM runoob_transaction_test;

2、直接用 SET 來改變 MySQL 的自動提交模式:

-- 禁止自動提交
SET AUTOCOMMIT=0
--開啟自動提交
SET AUTOCOMMIT=1 

三、儲存過程

3.1、什麼是儲存過程

儲存過程(Stored Procedure)是一種在資料庫中儲存複雜程式,以便外部程式呼叫的一種資料庫物件。

儲存過程是為了完成特定功能的SQL語句集,經編譯建立並儲存在資料庫中,使用者可通過指定儲存過程的名字並給定引數(需要時)來呼叫執行。

儲存過程思想上很簡單,就是資料庫 SQL 語言層面的程式碼封裝與重用。

3.2、儲存過程的優點

儲存過程可封裝,並隱藏複雜的商業邏輯。 儲存過程可以回傳值,並可以接受引數。 儲存過程無法使用 SELECT 指令來執行,因為它是子程式,與檢視 表,資料表或使用者定義函式不同。 儲存過程可以用在資料檢驗,強制實行商業邏輯等。

3.3、建立儲存過程

# 建立儲存過程
DELIMITER $
CREATE PROCEDURE testa()
BEGIN
    SELECT * FROM student;
    SELECT * FROM cj;
END $
DELIMITER ;

呼叫

# 呼叫
CALL testa();

3.4、儲存過程的變數以及作用範圍

# 建立儲存過程
DELIMITER $
CREATE PROCEDURE test2()
BEGIN
    # 宣告變數型別
    DECLARE un VARCHAR(32) DEFAULT '';
    # 給username賦值
    SET un='xiaoxiao';
    # 將查詢結果賦值給un變數
    SELECT username INTO un FROM student WHERE stuid=3;
    # 查詢un變數,返回
    SELECT un;
END $
DELIMITER ;
# 呼叫儲存過程
CALL test2();

# 變數的作用範圍
DELIMITER $
CREATE PROCEDURE test3()
BEGIN
    BEGIN
        # 宣告變數型別
        DECLARE un VARCHAR(32) DEFAULT '';
        # 給un賦值
        SET un='xiaoxiao';
        # 將查詢結果賦值給un變數
        SELECT username INTO un FROM student WHERE stuid=3;
        # 查詢un變數,返回
        SELECT un;
    END;
    BEGIN
        # 宣告變數型別
        DECLARE un VARCHAR(32) DEFAULT '';
        # 給un賦值
        SET un='xiaoxiao';
        # 將查詢結果賦值給un變數
        SELECT username INTO un FROM student WHERE stuid=4;
        # 查詢un變數,返回
        SELECT un;
    END;
    
END $
DELIMITER ;
# 呼叫儲存過程
CALL test3();

四、觸發器

4.1、什麼是觸發器      

觸發器(trigger):監視某種情況,並觸發某種操作,它是提供給程式設計師和資料分析員來保證資料完整性的一種方法,它是與表事件相關的特殊的儲存過程,

它的執行不是由程式呼叫,也不是手工啟動,而是由事件來觸發,例如當對一個表進行操作( insert,delete, update)時就會啟用它執行。

觸發器經常用於加強資料的完整性約束和業務規則等。 觸發器建立語法四要素:

1.監視地點(table)

2.監視事件(insert/update/delete)

3.觸發時間(after/before)

4.觸發事件(insert/update/delete)

4.2、建立觸發器

USE info;
# 學生表
CREATE TABLE IF NOT EXISTS student(
    username VARCHAR(50),
    PASSWORD VARCHAR(50),
    stuid INT PRIMARY KEY AUTO_INCREMENT,
    birthday DATE
);
INSERT INTO student(username,PASSWORD,birthday)VALUES
('王二','111111','2016-08-23'),
('李四','123456','2016-07-23'),
('楊三','123456','2016-08-17'),
('劉五','000000','2016-08-18'),
('黃六','666666','2016-08-23');
SELECT * FROM student;
# 成績表
CREATE TABLE IF NOT EXISTS cj(
    num INT PRIMARY KEY AUTO_INCREMENT,
    stu_id INT,
    stu_name VARCHAR(50),
    math FLOAT,
    chinese FLOAT,
    english FLOAT
);
SELECT * FROM cj;
# 觸發器
DELIMITER $
CREATE TRIGGER ins_stu
AFTER INSERT ON student FOR EACH ROW
BEGIN
    INSERT INTO cj(stu_id,stu_name,math,chinese,english)
    VALUES(new.stuid,new.username,88,88,88);
END $
DELIMITER ;
# 執行觸發過程
INSERT INTO student(username,PASSWORD,birthday)VALUES
('張三','222222','2016-08-23');