数据库基本知识梳理
1. 主鍵與索引的區別:
1:主鍵是為了標識數據庫記錄唯一性,不允許記錄重復,且鍵值不能為空,主鍵也是一個特殊索引.
2:數據表中只允許有一個主鍵,但是可以有多個索引.
3.使用主鍵會數據庫會自動創建主索引,也可以在非主鍵上創建索引,方便查詢效率.
4:索引可以提高查詢速度,它就相當于字典的目錄,可以通過它很快查詢到想要的結果,而不需要進行全表掃描.
5:主鍵索引外索引的值可以為空.?
6:主鍵也可以由多個字段組成,組成復合主鍵,同時主鍵肯定也是唯一索引.
7:唯一索引則表示該索引值唯一,可以由一個或幾個字段組成,一個表可以有多個唯一索引.
主鍵的索引默認為聚集索引
主鍵 | 聚集索引 | |
| 用途 | 強制表的實體完整性 | 對數據行的排序,方便查詢用 |
| 一個表多少個 | 一個表最多一個主鍵 | 一個表最多一個聚集索引 |
| 是否允許多個字段來定義 | 一個主鍵可以多個字段來定義 | 一個索引可以多個字段來定義 |
| ? | ? | ? |
| 是否允許 null 數據行出現 | 如果要創建的數據列中數據存在null,無法建立主鍵。 創建表時指定的 PRIMARY KEY 約束列隱式轉換為 NOT NULL。 | 沒有限制建立聚集索引的列一定必須 not null . 也就是可以列的數據是 null 參看最后一項比較 |
| 是否要求數據必須唯一 | 要求數據必須唯一 | 數據即可以唯一,也可以不唯一。看你定義這個索引的 UNIQUE 設置。 (這一點需要看后面的一個比較,雖然你的數據列可能不唯一,但是系統會替你產生一個你看不到的唯一列) |
| ? | ? | ? |
| 創建的邏輯 | 數據庫在創建主鍵同時,會自動建立一個唯一索引。 如果這個表之前沒有聚集索引,同時建立主鍵時候沒有強制指定使用非聚集索引,則建立主鍵時候,同時建立一個唯一的聚集索引 | 如果未使用 UNIQUE 屬性創建聚集索引,數據庫引擎 將向表自動添加一個四字節 uniqueifier 列。 必要時,數據庫引擎 將向行自動添加一個 uniqueifier 值,使每個鍵唯一。此列和列值供內部使用,用戶不能查看或訪問。 |
2. 數據庫索引的分類及優缺點 ?
數據庫的索引分為:聚集索引,非聚集索引,唯一索引。
優點:方便了查詢,在數據量大時排序更易查詢,
缺點:查詢時需要進行重新排序,減少了效率。物理索引缺點 建立索引效率低,只能建一個。
為什么要創建索引呢?這是因為,創建索引可以大大提高系統的性能。第一,通過創建唯一性索引,可以保證數據庫表中每一行數據的唯一性(如果不用unique修飾,可以有重復值)。第二,可以大大加快數據的檢索速度,這也是創建索引的最主要的原因。第三,可以加速表和表之間的連接,特別是在實現數據的參考完整性方面特別有意義。第四,在使用分組和排序子句進行數據檢索時,同樣可以顯著減少查詢中分組和排序的時間。第五,通過使用索引,可以在查詢的過程中,使用優化隱藏器,提高系統的性能。
也許會有人要問:增加索引有如此多的優點,為什么不對表中的每一個列創建一個索引呢?這種想法固然有其合理性,然而也有其片面性。雖然,索引有許多優點,但是,為表中的每一個列都增加索引,是非常不明智的。這是因為,增加索引也有許多不利的一個方面。第一,創建索引和維護索引要耗費時間,這種時間隨著數據量的增加而增加。第二,索引需要占物理空間,除了數據表占數據空間之外,每一個索引還要占一定的物理空間,如果要建立聚簇索引,那么需要的空間就會更大。第三,當對表中的數據進行增加、刪除和修改的時候,索引也要動態的維護,這樣就降低了數據的維護速度。
索引是建立在數據庫表中的某些列的上面。因此,在創建索引的時候,應該仔細考慮在哪些列上可以創建索引,在哪些列上不能創建索引。一般來說,應該在這些列上創建索引,例如:在經常需要搜索的列上,可以加快搜索的速度;在作為主鍵的列上,強制該列的唯一性和組織表中數據的排列結構;在經常用在連接的列上,這些列主要是一些外鍵,可以加快連接的速度;在經常需要根據范圍進行搜索的列上創建索引,因為索引已經排序,其指定的范圍是連續的;在經常需要排序的列上創建索引,因為索引已經排序,這樣查詢可以利用索引的排序,加快排序查詢時間;在經常使用在WHERE子句中的列上面創建索引,加快條件的判斷速度。
同樣,對于有些列不應該創建索引。一般來說,不應該創建索引的的這些列具有下列特點:第一,對于那些在查詢中很少使用或者參考的列不應該創建索引。這是因為,既然這些列很少使用到,因此有索引或者無索引,并不能提高查詢速度。相反,由于增加了索引,反而降低了系統的維護速度和增大了空間需求。第二,對于那些只有很少數據值的列也不應該增加索引。這是因為,由于這些列的取值很少,例如人事表的性別列,在查詢的結果中,結果集的數據行占了表中數據行的很大比例,即需要在表中搜索的數據行的比例很大。增加索引,并不能明顯加快檢索速度。第三,對于那些定義為text, image和bit數據類型的列不應該增加索引。這是因為,這些列的數據量要么相當大,要么取值很少。第四,當修改性能遠遠大于檢索性能時,不應該創建索引。這是因為,修改性能和檢索性能是互相矛盾的。當增加索引時,會提高檢索性能,但是會降低修改性能。當減少索引時,會提高修改性能,降低檢索性能。因此,當修改性能遠遠大于檢索性能時,不應該創建索引。
聚集索引、非聚集索引
什么是聚集索引??
漢語字典的正文本身就是一個聚集索引。比如,我們要查“安”字,就會很自然地翻開字典的前幾頁,因為“安”的拼音是“an”,而按照拼音排序漢字的字典是以英文字母“a”開頭并以“z”結尾的,那么“安”字就自然地排在字典的前部。如果您翻完了所有以“a”開頭的部分仍然找不到這個字,那么就說明您的字典中沒有這個字;同樣的,如果查“張”字,那您也會將您的字典翻到最后部分,因為“張”的拼音是“zhang”。也就是說,字典的正文部分本身就是一個目錄,您不需要再去查其他目錄來找到您需要找的內容。正文內容本身就是一種按照一定規則排列的目錄稱為“聚集索引”。每個表只能有一個聚集索引,因為目錄只能按照一種方法進行排序。
什么是非聚集索引??
?如果您認識某個字,您可以快速地從自動中查到這個字。但您也可能會遇到您不認識的字,不知道它的發音,這時候,您就不能按照剛才的方法找到您要查的字,而需要去根據“偏旁部首”查到您要找的字,然后根據這個字后的頁碼直接翻到某頁來找到您要找的字。但您結合“部首目錄”和“檢字表”而查到的字的排序并不是真正的正文的排序方法,比如您查“張”字,我們可以看到在查部首之后的檢字表中“張”的頁碼是672頁,檢字表中“張”的上面是“馳”字,但頁碼卻是63頁,“張”的下面是“弩”字,頁面是390頁。很顯然,這些字并不是真正的分別位于“張”字的上下方,現在您看到的連續的“馳、張、弩”三字實際上就是他們在非聚集索引中的排序,是字典正文中的字在非聚集索引中的映射。我們可以通過這種方式來找到您所需要的字,但它需要兩個過程,先找到目錄中的結果,然后再翻到您所需要的頁碼。我們把這種目錄純粹是目錄,正文純粹是正文的排序方式稱為“非聚集索引”。
?第一:聚集索引的約束是唯一性,是否要求字段也是唯一的呢?
??????? 分析:如果認為是的朋友,可能是受系統默認設置的影響,一般我們指定一個表的主鍵,如果這個表之前沒有聚集索引,同時建立主鍵時候沒有強制指定使用非聚集索引,SQL會默認在此字段上創建一個聚集索引,而主鍵都是唯一的,所以理所當然的認為創建聚集索引的字段也需要唯一。
??????? 結論:聚集索引可以創建在任何一列你想創建的字段上,這是從理論上講,實際情況并不能隨便指定,否則在性能上會是惡夢。
????????
??????? 第二:為什么聚集索引可以創建在任何一列上,如果此表沒有主鍵約束,即有可能存在重復行數據呢?
??????? 粗一看,這還真是和聚集索引的約束相背,但實際情況真可以創建聚集索引,分析其原因是:如果未使用 UNIQUE 屬性創建聚集索引,數據庫引擎將向表自動添加一個四字節 uniqueifier 列。必要時,數據庫引擎 將向行自動添加一個 uniqueifier 值,使每個鍵唯一。此列和列值供內部使用,用戶不能查看或訪問。
????????????
??????? 第三:是不是聚集索引就一定要比非聚集索引性能優呢?
??????? 如果想查詢學分在60-90之間的學生的學分以及姓名,在學分上創建聚集索引是否是最優的呢?
??????? 答:否。既然只輸出兩列,我們可以在學分以及學生姓名上創建聯合非聚集索引,此時的索引就形成了覆蓋索引,即索引所存儲的內容就是最終輸出的數據,這種索引在比以學分為聚集索引做查詢性能更好。
????????
??????? 第四:在數據庫中通過什么描述聚集索引與非聚集索引的?
??????? 索引是通過二叉樹的形式進行描述的,我們可以這樣區分聚集與非聚集索引的區別:聚集索引的葉節點就是最終的數據節點,而非聚集索引的葉節仍然是索引節點,但它有一個指向最終數據的指針。
????????
??????? 第五:在主鍵是創建聚集索引的表在數據插入上為什么比主鍵上創建非聚集索引表速度要慢?
??????? 有了上面第四點的認識,我們分析這個問題就有把握了,在有主鍵的表中插入數據行,由于有主鍵唯一性的約束,所以需要保證插入的數據沒有重復。我們來比較下主鍵為聚集索引和非聚集索引的查找情況:聚集索引由于索引葉節點就是數據頁,所以如果想檢查主鍵的唯一性,需要遍歷所有數據節點才行,但非聚集索引不同,由于非聚集索引上已經包含了主鍵值,所以查找主鍵唯一性,只需要遍歷所有的索引頁就行,這比遍歷所有數據行減少了不少IO消耗。這就是為什么主鍵上創建非聚集索引比主鍵上創建聚集索引在插入數據時要快的真正原因。
????????
??????? 好了,講這這些,不知道大家是否真的了解SQL的聚焦索引,我也是數據庫新手(從使用時間上來講也不算新了,哈哈),不專業,有什么不對的地方,希望大家批評指正,下篇我會分析一些數據庫訪問索引的情況,有圖的情況下,也許看的更加明白。
聚簇索引的順序就是數據的物理存儲順序,而對非聚簇索引的解釋是:索引順序與數據物理排列順序無關。正式因為如此,所以一個表最多只能有一個聚簇索引。
聚簇索引的葉節點就是數據節點,而非聚簇索引的頁節點仍然是索引檢點,并保留一個鏈接指向對應數據塊。
在主鍵上建立聚簇索引會比較慢,主鍵約束要求主鍵不能出現重復,那么SQL Server是怎么知道不出現重復的呢?唯一的方法就是檢索。對于非聚簇索引,只需要檢索20個頁面中的16000個節點就知道是否有重復,因為所有主鍵鍵值在這16000個索引節點中都包含了。但對于聚簇索引,索引節點僅僅包含了8000個中間節點,至于會不會出現重復必須檢索另外1000個頁數據節點才知道,那么相當于檢索10+1000=1010個頁面才知道是否有重復。所以聚簇索引主鍵的插入速度要比非聚簇索引主鍵的插入速度慢很多。
總結
- 上一篇: 二叉树的高度和节点数
- 下一篇: 数据库 活锁和死锁