1. 程式人生 > >MySQL中索引、檢視、觸發器詳解

MySQL中索引、檢視、觸發器詳解

一、索引

1.概述

  所有 MySQL 列型別都可以被索引,對相關列使用索引是提高 SELECT 操作效能的最佳途
徑。根據儲存引擎可以定義每個表的最大索引數和最大索引長度,每種儲存引擎(如 MyISAM、
InnoDB、BDB、MEMORY 等)對每個表至少支援 16 個索引,總索引長度至少為 256 位元組。
大多數儲存引擎有更高的限制。
一個表的索引,就好比一本書的目錄。有了目錄,查詢速度自然會大大加快。

2.語法

建立:

CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name
	[USING index_type]
	ON tbl_name (index_col_name,...)

index_col_name:
	col_name [(length)] [ASC | DESC]

刪除:

DROP INDEX index_name ON tbl_name

3. 案例實現

建立:

create index index_book on book_info(book_name);

刪除:

drop index index_book on book_info;

4:使用原則

  • 搜尋的索引列,不一定是所要選擇的列。 換句話說,最適合索引的列是出現在 WHERE
    子句中的列,或連線子句中指定的列,而不是出現在 SELECT 關鍵字後的選擇列表中的列。

  • 使用惟一索引。 索引的列的基數越大,索引的效果越好。例如,存放出生日期的列具有不同值,很容易區分各行。

  • 使用短索引。 如果對字串列進行索引,應該指定一個字首長度,只要有可能就應
    該這樣做。這樣做比對整個列進行索引的速度更快。

  • 利用最左字首。 在建立一個 n 列的索引時,實際是建立了 MySQL 可利用的 n 個索引。
    多列索引可起幾個索引的作用,因為可利用索引中最左邊的列集來匹配行。這樣的列集稱為
    最左字首。

  • 不要過度索引。 每個索引都會佔用你的磁碟空間,每個表跟新的時候也需要更新索引。索引太多時,mysql可能會選擇不到適合的索引,只保留有用的索引,才可優化查詢速度。

二、檢視

1.概述

  檢視(View)是一種虛擬存在的表,對於使用檢視的使用者來說基本上是透明的。檢視並
不在資料庫中實際存在,行和列資料來自定義檢視的查詢中使用的表,並且是在使用檢視時
動態生成的。簡單來說,檢視就是呈現給使用者資料的一個虛擬表,只能檢視,不會對原表產生任何影響。

2.不可更新的檢視

  MySQL 檢視的定義有一些限制,例如,在 FROM 關鍵字後面不能包含子查詢,這和其他資料庫是不同的,如果檢視是從其他資料庫遷移過來的,那麼可能需要因此做一些改動,可以將子查詢的內容先定義成一個檢視,然後對該檢視再建立檢視就可以實現類似的功能了。檢視的可更新性和檢視中查詢的定義有關係,以下型別的檢視是不可更新的。

  • 包含以下關鍵字的 SQL 語句:聚合函式(SUM、MIN、MAX、COUNT 等)、DISTINCT、GROUP
    BY、HAVING、UNION 或者 UNION ALL。
  • 常量檢視。
  • SELECT 中包含子查詢。
  • JION。
  • FROM 一個不能更新的檢視。
  • WHERE 字句的子查詢引用了 FROM 字句中的表。

3.語法

建立:

CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
	VIEW view_name [(column_list)]
	AS select_statement
	[WITH [CASCADED | LOCAL] CHECK OPTION]

修改:

ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
	VIEW view_name [(column_list)]
	AS select_statement
	[WITH [CASCADED | LOCAL] CHECK OPTION]

刪除:

DROP VIEW [IF EXISTS] view_name [, view_name] ...[RESTRICT | CASCADE]

4.案例

建立:

create view book_view as
	select * from book_info b 
	inner join press_info p
	on b.press_id = p.press_id

刪除:

drop view book_view

三、觸發器

1.概述

  觸發器是與表有關的資料庫物件,在滿足定義條件時觸發,並執行觸發器中定義的語句集合。觸發器的這種特性可以協助應用在資料庫端確保資料的完整性。

2.語法

建立:

CREATE TRIGGER trigger_name trigger_time trigger_event
ON tbl_name FOR EACH ROW trigger_stmt

刪除:

DROP TRIGGER [schema_name.]trigger_name

檢視觸發器:

-- 第一種,系統自帶
show triggers \G;
-- 第二種,檢視方式是查詢系統表的 information_schema.triggers 表
desc triggers;

注意: 觸發器只能建立在永久表(Permanent Table)上,不能對臨時表(Temporary Table)建立觸發器。

其中 triggertime 是觸發器的觸發時間,可以是 BEFORE 或者 AFTER,BEFORE 的含義指在檢
查約束前觸發,而 AFTER 是在檢查約束後觸發。
而 triggerevent 就是觸發器的觸發事件,可以是 INSERT、UPDATE 或者 DELETE。

3.案例

-- 每更新一次press_info表的資料,都向t_log表插入一條操作資料
create trigger tri_updinfo
after update on press_info for each row
	insert into t_log (notes) values ('update press_info');
end;

4.觸發器的使用

觸發器執行的語句有以下兩個限制。

  • 觸發程式不能呼叫將資料返回客戶端的儲存程式,也不能使用採用 CALL 語句的動態 SQL
    語句,但是允許儲存程式通過引數將資料返回觸發程式。也就是儲存過程或者函式通過 OUT
    或者 INOUT 型別的引數將資料返回觸發器是可以的,但是不能呼叫直接返回資料的過程。
  • 不能在觸發器中使用以顯式或隱式方式開始或結束事務的語句,如 START TRANSACTION、
    COMMIT 或 ROLLBACK。

MySQL 的觸發器是按照 BEFORE 觸發器、行操作、AFTER 觸發器的順序執行的,其中任何一
步操作發生錯誤都不會繼續執行剩下的操作。如果是對事務表進行的操作,那麼會整個作為
一個事務被回滾(Rollback),但是如果是對非事務表進行的操作,那麼已經更新的記錄將無
法回滾,這也是設計觸發器的時候需要注意的問題。

5.小結

需要注意的是觸發器是行觸發的,每次增加、修改或者刪除記錄都會觸發進行處理,編寫過於複雜的觸發器或者增加過多的觸發器對記錄的插入、更新、刪除操作肯定會有比較嚴重的影響,因此資料庫設
計的時候要有所考慮,不要將應用的處理邏輯過多的依賴於觸發器來處理