MySQL 視圖、索引、外鍵關聯策略


 

視圖

視圖是一張虛表,將查詢結果集保存起來,作爲視圖使用。實際存在的表叫作基本表。
 

視圖的作用

  • 提高安全性。grant授權用戶只能操作視圖,通過視圖來操作基本表,可以保護基本表中的數據
  • 提高查詢性能。視圖只是基本表的一部分,查視圖比查全錶快。尤其是多表查詢的時候,查視圖一張表比連接多張表查詢要快很多

 

視圖常用操作

-- 創建視圖,as指定結果集,假設cs系的id是1
create view view_dep_cs as (select * from tb_student where dep_id=1);  -- 可以把這個視圖作爲cs系學生信息表來使用


-- 修改視圖定義,用新結果集覆蓋原來的結果集。如果視圖不存在,會自動創建
create or replace view view_cs_dep as (select id,name from tb_student where dep_id=1);  


-- 從視圖查詢數據
select * from view_dep_cs where name='chy';  --查詢cs系名字是chy的學生


-- 刪除視圖
drop view view_cs_dep;

 

創建視圖的完整語法

create [algorithm=merge] view view_dep_cs as (select * from tb_student where dep_id=1) [with check option] ;

algorithm指定視圖執行機制,有3個可選的值

1、merge 合併

不創建臨時表,執行時會先用視圖定義替換視圖名,每次都是操作基本表,並不會提高查詢性能,但可以增改刪查。
 

2、temptable 臨時表

把結果集保存爲臨時表,每次操作的都是臨時表,可以提高查詢性能,但只讀,不能增刪改。
 

3、undefined 未定義
不指定algorithm就是undefined,使用數據庫設置的默認值,mysql默認使用merge。

 

如果使用merge,還可以設置一個可選參數:with check option 檢查條件。

創建視圖時設置了條件where dep_id=1,即視圖中的記錄都是dep_id=1的。

如果指定了with check option,往視圖中插入、更新記錄時,都要滿足記錄的dep_id=1這個條件,否則不執行操作;如果不指定with check option,則不要求dep_id=1。

使用merge時往往要設置with check option。

 

不可更新的視圖

即使使用merge,也不一定可以進行增刪改,as指定視圖數據來源,如果視圖來源中使用了一下任一項,則創建的視圖只讀(只能查詢)、不能增刪改

  • 聚合函數
  • group by子句
  • having子句
  • distinct關鍵字
  • union運算符
  • from來源於多個表或者來源於不可更新的視圖

一句話:不是直接來源於一個基本表的視圖,則該視圖只讀、不能更新視圖數據。

 

索引

不使用索引時,要操作某些記錄,需要遍歷整張表來找到匹配的記錄,時間開銷大。

索引相當於數據表的目錄,根據目錄可直接定位到章節,根據索引可直接定位到數據表的記錄,無需遍歷整張表。

 

索引的優缺點

  • 極大提高了檢索速度,尤其是記錄數很多的時候(優)
  • 索引也是一張表,要佔硬盤空間,有額外的空間開銷(缺)
  • 對基本表進行增改刪時會同步到索引(維護索引),有額外的時間、資源開銷(缺)

相較於優點,索引的缺點微不足道。

 

常見的幾種索引

  • 單值索引:索引中只包含數據表的一列(一個字段)
  • 唯一索引:索引中列的值唯一,一般是數據表的主鍵列
  • 複合索引:也叫作聯合索引,索引中包含數據表的多個列
  • 全文索引:只能對MyISAM引擎的表使用,且索引中的列要是char、varchar、text等文本類型

 

索引常用操作

create index index_ts on tb_user(id,name);  -- on指定使用哪張表的哪些字段來創建索引。經常使用學號、姓名定位學生(記錄),所以使用這2列創建索引
 
show index from tb_student;  -- 查看某個表上所有的索引
 
drop index index_ts on tb_student;  -- 刪除索引

索引、視圖都可以在數據庫管理工具(比如Navicat)中直接操作。索引是在 “設計表” 中操作的。

 

常用的索引方式

1、b+樹(最常用)

eg. 以id字段創建索引,假設有7條記錄,id 1~7
在這裏插入圖片描述
查找id=7的記錄的地址:4 -> 6 -> 7
 

2、hash  通過hash值一次直接找到記錄的地址

eg. 使用id字段建立索引,查找id=7的記錄:計算7的hash值 -> 根據hash值直接確定記錄在表中的位置。
 

b+樹要一級一級地找,hash直接定位,效率遠高於btree。但一般都是使用b+樹,因爲大多數存儲引擎都支持b+樹,hash只有memory存儲引擎支持。

 

哪些字段適合創建索引?

  • 主鍵
  • 外鍵
  • 頻繁作爲條件的字段。eg. 經常要用where name=’ ',那就給name字段創建索引
  • group by分組使用的字段
  • order by排序使用的字段
  • 統計(聚合函數)使用的字段

 

建立索引有額外的空間開銷,增改刪時維護索引也有額外的時間開銷,記錄數少的表沒必要創建索引;頻繁增改刪的字段,維護索引開銷大,不適合用來創建索引。

添加主鍵時,會自動給主鍵列創建唯一索引(Unique);添加外鍵時,會自動給外鍵列創建普通索引(Normal)。

創建索引後,從表中找匹配的記錄時會自動選擇合適的索引來使用,不需要我們指定索引。

 

外鍵關聯策略

eg. tb_order通過外鍵user_id關聯tb_user的主鍵id,當update、delete tb_user的id時,如何處理與之對應的tb_order中的記錄?
在這裏插入圖片描述
設計外鍵時,mysql提供了4種外鍵關聯策略

1、RESTRICT  限制(默認)

如果有外鍵關聯了tb_user的id,則tb_user不能刪除被關聯的記錄、不能更新關聯記錄id字段的值(會報錯)。

如果要刪除記錄、更新id字段的值,需要先切斷關聯關係,比如先刪除tb_order中與之關聯的記錄、或者把相關記錄外鍵字段的值置爲null。

 

2、CASCADE  級聯(最常用)

刪除tb_user中的記錄時,會自動刪除tb_order中與之關聯的記錄;修改tb_user中id字段的值時,會自動修改tb_order中與之關聯的記錄的外鍵字段的值(同步變化)。

 

3、NO ACTION  什麼都不做

刪除、更新tb_user中的user_id字段的值時,tb_order中與之關聯的記錄不作任何處理。此種策略需要存儲引擎支持,如果存儲引擎不支持,會自動換爲RESTRICT。

 

4、SET NULL  置爲NULL

刪除tb_user的記錄,或者更新id字段的值,會自動將tb_order中與之關聯的記錄的外鍵字段的值置爲NULL。

這種方式有一個要求:設計tb_order時,外鍵字段不能用NOT NULL約束。

 

一般使用CASCADE,未設置外鍵關聯策略時默認爲RESTRICT(爲了數據安全)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章