索引
是什么
類似于目錄,提高查詢的速度,但是本身會占用空間,增刪數據的時候也需要維護索引。所以查詢操作頻繁的時候可以創建索引。如果非條件查詢列,或經常做插入、修改操作,或磁盤空間不足時,不考慮創建索引。
創建主鍵約束(primary key),唯一約束(unique),外鍵約束(foreign key)時會自動創建對應列索引。
查詢索引??
show index? ?from? 表名;
創建索引
當數據庫的數據量很大時,創建和刪除索引是很危險的操作,會大量消耗CPU,IO等資源,可能導致數據庫卡死。所以要在放入數據之前,或者數據庫中的數據量不大時創建索引。如果要給一個數據量很大的數據庫添加索引,就需要再準備一個服務器,在空的數據庫中創建好索引,將另一個數據庫的數據慢慢導入這個空的數據庫里。
create? ?index? ?索引名? ?on? ? 表名(列名?);//底層是創建出一棵獨立的B+樹來組織索引,跟主鍵的B+樹沒有關聯。是兩棵獨立的樹。
刪除索引
drop index? ?索引名? ? on? ?表名 ;
底層結構
數據庫的索引是用B+樹表示存儲的。
B+樹結構
僅葉子節點存儲數據并通過鏈表指針連接(葉子節點從左到右是有序的,且存儲在一塊連續內存空間,避免頻繁訪問硬盤,一次硬盤IO就能讀出整個節點數據;訪問的數據都在葉子節點,樹高一樣,則每次查詢次數是穩定的);
非葉子節點存儲鍵,鍵值為其葉子節點中的最大值(方便進行范圍查詢,鎖定葉子節點中數據的位置);
當葉子節點個數達到閾值,會進行分叉。(索引在內存中,個數增加了對速度影響不大,但葉子節點存在硬盤中,訪問硬盤的速度比訪問內存滿很多,所以要進行分叉,根據索引查找數據時范圍更精確)
1.N叉搜索樹(多叉樹可以控制樹的高度)
2.父節點以葉子節點中最大值的形式存在(快速鎖定子樹的數據范圍)
3.葉子節點這一層用鏈表結構連上,不用再回溯到父節點。(范圍查尋更高效)
4.數據存儲在葉子節點,索引存在非葉子節點中,因為占用空間小,索引就存在內存中。(索引在內存中加快查找速度)
為什么用B+樹,不用其他數據結構?
AVL樹是嚴格的自平衡二叉搜索樹(子樹高度差不能超過1),隨便進行一下增刪改就會觸發AVL樹旋轉。每一次旋轉都有對應的開銷,所以用AVL樹除了查詢外,其他操作的效率不高,每一次增刪都需要維護樹的平衡;
而紅黑樹雖然旋轉的概率沒有AVL樹高,但他是二叉樹,當數據量很大時,樹的高度就會很高,高度每增加一層,查詢比較次數就多一次,而數據庫數據索引是存儲在硬盤上的,每一次對硬盤的IO操作很耗時間,查詢的速度就會慢很多;
hash表存儲數據是無序的,不能進行范圍查詢(不能用>或者<找到一個范圍的數據),只能比較相同key值的數據,因為經過hash函數的計算,原來key之間的大小關系 已經不能通過計算出來的hash值反應了。
事務
什么是事務
當實現一個目的需要多個sql語句執行時,將這些sql語句打包成的一個整體,稱作事務。事務中的sql語句要么全部執行成功,要么全部失敗。對于轉賬這類場景,開啟事務更能保證安全。當A給B轉賬500,A的賬號-500,如果設備發生故障,sql沒執行完,B的賬戶沒有+500,如果沒有開啟事務,那么這500就消失了。開啟事務后,出現故障后,會撤銷對A賬戶執行的操作,將A賬號的金額還原到轉賬前。
使用
1.start? transaction ;//開啟事務
2.中間執行多個sql語句
3.rollback或commit??
rollback表示回滾,中間的sql語句全部執行失敗,commit表示提交,sql全部執行成功。
進行回滾了,name為a的數據沒有插入成功。
基本特性
1.原子性
事務里的sql語句執行要么都成功執行,要么都不執行。當一部分sql語句執行成功,出現網絡崩潰,計算機死機,主機掉電等操作時,像網絡崩潰這種不影響數據庫的,則會執行回滾操作,將已經執行的sql語句造成的影響恢復到沒執行時候的情況。當事務執行時,sql語句會記錄在mysql日志中,像主機掉電這種情況,數據庫沒辦法運行的時候,也不影響執行回滾操作,當電來了,恢復正常,數據庫會根據日志信息執行回滾。
2.一致性
執行事務之后,數據能對得上;事務沒執行成功,執行回滾后,能與執行事務之前數據一樣。
3.持久性
持久性指數據被存在硬盤上,主機/程序重啟后,數據依然存在。事務執行具有持久性,對數據庫造成的修改,會保存在硬盤上持久存在。
4.隔離性
在執行并發操作時存在的概念。隔離性提高,并發能力就降低,數據庫服務器執行效率就會降低,但數據準確性會提高?。當多個客戶端同時對服務器發起事務時,可能存在下面幾種情況。
1.臟讀問題:讀取到其他事務未提交的數據
當執行事務A對某一張表做一些修改時,事務B在事務A還沒執行完就來讀取這張表的數據,但是B這時讀取的表的數據是臨時的,B如果基于這個臨時數據進行一些操作,結果可能不正確。這樣導致的問題稱作臟讀問題,這個臨時數據也稱‘臟數據’。
2.不可重復讀問題:指同一事務內相同查詢條件多次執行結果不同(數據值被修改)
當事務B有多個讀的操作時,有一個事務C要對這張 表做修改,這樣可能導致事務B多個讀的結果前后不一致。
3.幻讀問題:指同一事務內相同范圍查詢返回的行數發生變化(新增或刪除行),這是不可重復讀的特殊情況。
MySQL 的四個隔離等級
可以在MySQL的配置文件中設置等級
1.read uncommitted:允許讀取其他事務未提交的數據? ;//存在臟讀+不可重復讀+幻讀,
這樣就是降低了并發時事務之間的影響,提高了隔離性,犧牲了部分效率,提高了數據準確性。
2.read? committed:只能讀取其他事務提交后的數據;//解決臟讀 ,存在不可重復讀+幻讀,進一步降低了并發性,提高安全性。
3.repeatable? read: 針對讀和寫操作都加鎖了;//解決了臟讀+不可重復讀,存在幻讀問題 (MySQL默認隔離等級)
4.串行化(serialiable) :所有事務串行執行;//嚴格的一個接一個執行,這時完全沒有并發,也就不存在上訴三個問題;隔離性是最高的,效率是最低的。