主鍵索引和次級索引

2021-10-18 03:16:39 字數 2583 閱讀 4016

但是索引頁可能有5頁。也就是說這個索引頁是附加的。

資料以塊儲存在磁碟上(假設在磁碟上),那所有這些資料庫就像鍊錶一樣被訪問,就是自己儲存一塊,然後有個指標指向相鄰的下一塊(差不多這意思),既然是有連續的指標。不需要連續儲存的。

對乙個表,我們只能對一列進行排序。如果我們去查詢沒排序的字段,假設這個表有n個塊,那線性搜尋平均需要訪問n/2塊。最大是n塊。因為需要不停對查詢到的列做比較。這還是針對是主鍵(唯一鍵),如果你要查詢的不是唯一鍵,那就得查詢n塊。

如果字段排序了,那就二分法查詢。就只需要訪問log2n塊。

如果對非主鍵字段進行排序,那對比乙個高值,其實就等於對比了很多個高值,所以就提公升了很大的效能啊。

從上面能看出來,資料庫索引是對多個欄位的記錄值進行排序。 你建了乙個表的某個字段(或多個字段)的索引,就是建了乙個有字段值,和指向表中記錄位置的指標的乙個結構。這個指標結構會被排序。允許二分查詢。

壞處就是,索引也佔記憶體啊。

而且改了表,索引也要更新啊。

我們來看乙個具體的表的例子:

假設表字段這樣的:

欄位名 | 資料型別 | 佔磁碟空間

-------- | ----- | -----

id(主鍵) | int | 4 bytes

name | char(50) | 50 bytes

*** | char(50) | 50 bytes

address | char(100) | 100 bytes

假定我們這個表有10000個固定大小的記錄。

每條記錄的長度就為204個位元組,預設磁碟塊大小是b=1024bytes,也就是乙個磁碟塊可以放1024/204=5條記錄。要儲存這個表記錄需要10000/5=2000個磁碟塊。

對id進行線性查詢需要平均2000/2=1000次訪問。但是它是主鍵,所以可以進行二分查詢,就只需要log2 (2000) = 10.9次訪問。就11次。

如果你對非主鍵name進行訪問,那就得需要遍歷2000次。

所以咱對name建個索引。

欄位名 | 資料型別 | 佔磁碟空間

-------- | ----- | -----

name | char(50) | 50 bytes

pointer | special | 4 bytes

所以索引是54個位元組。預設磁碟塊1024個位元組。所以每個磁碟塊可以有18條記錄。索引將要占用磁碟塊10000/18 = 555.555個。

那麼在這個索引上先找name就需要乙個二分查詢,需要查詢log2 (555.5) = 9次,就是要找9塊磁碟塊。然後在name基礎上查詢address就只需要再找一塊,就是10塊。

跟原先去找10000個相比,快多了。

這樣一看,索引真好。但是別忘了,索引占用了555個磁碟塊啊,對比表記錄的2000個磁碟塊,直接用上了25%還多的空間啊。

所以說,索引很佔空間。 即使他能幫我們大大加快查詢條目中的匹配字段,但是當你去執行插入或者刪除操作的時候,弊端就來了。

所以,要考慮清楚用哪個欄位來建。因為二分查詢對資料唯一性的要求很高。另外這裡還要考慮資料基數。也就表的列中的資料,特別是其中有多少個唯一值。到這裡我又回去查了查資料庫,因為我完全不記得什麼基數,什麼是目數。維基百科上講cardinality是指資料庫表中特定列(屬性)中包含的資料值的唯一性。

那麼聯想到集合,集合包含3個元素,集合的基數就是集合中元素的個數,也就是說這裡的集合基數是3。

那我再延申一下,就是說這個基數那就是表中的一組行呀。

目數,是指表的屬性列。

而這個基數呢,首先要考慮資料的唯一性,如果你這列的行值又很多重複的,就1,2,1,2,1,2這種的,那你的基數就是2,如果這列的行值全是唯一的,那你這基數就是行數。

回到正題索引上,如果你這列的值基數是2,那你就等於在查詢資料的時候把整個資料表都一分為二了。如果你基數是1000,那就是找1000行。

這個意思就是說,如果你的列基數很低,那其實沒必要建索引的。列基數高才要建索引。就算列基數高時,索引佔空間,但是對查詢幫助很大。如果列基數低,索引雖然佔空間少,但是沒啥必要。列基數低於行數的30%,也就是說10行裡其實只有3個不同的值,那就沒必要用索引。

一般在咱資料庫表中,也不會用年月,數值等重複概率高的列做索引的。只會用id,編號之類的。

就是之前提到的,你更新的表有乙個索引,那就得實際上有兩個寫的操作,而且要重新排序index。如果表和索引都在乙個硬碟上,那就得花費更多的時間。所以,如果你把表和索引放在不同的硬碟上,可以節省時間。

另乙個問題就是這個資料不停的插入,導致索引的儲存碎片。這時候需要reorganize。這個我還真不知道怎麼搞呢。

索引佔據空間和寫操作。看你這個表是要經常寫還是要經常讀了。衡量是否需要建索引。

主鍵就是基於主鍵列並且沒有重複值的索引。

次級索引就是非主鍵索引,而且可以有重複值。

索引裡面有兩部分哈,乙個是查詢鍵,乙個是資料參照。

查詢鍵就是主鍵值或者其他列值,排了序的。資料參照包含個指標,儲存了查詢鍵在磁碟塊上的位址。

主鍵索引不是說只包含一列主鍵,而是說也可能是由很多列值,只是是組合值也是唯一的。

而且基於索引key是排序的。主鍵索引只能有乙個。

非主鍵索引,可以有重複值。

對行如何在資料塊裡組織的沒啥影響。可以有好多個呢。

嗯,還是去看書了。。。

主鍵索引和非主鍵索引

對於一張資料表,id為主鍵 非主鍵索引和主鍵索引的區別是 非主鍵索引的葉子節點存放的是主鍵的值,主鍵索引的葉子節點存放的是整行資料。其中,非主鍵索引又稱為二級索引,主鍵索引又稱為聚簇索引。根據這兩種結構我們來進行下查詢,看看他們在查詢上有什麼區別。1 如果查詢語句是 select from tabl...

mysql次級索引 MySQL 索引總結

1 索引是做什麼的?想象一下,你面前有本詞典,資料就是書的正文內容,你就是那個cpu,而索引,則是書的目錄 索引用於快速找出在某個列中有一特定值的行。不使用索引,mysql必須從第1條記錄開始然後讀完整個表直到找出相關的行。表越大,花費的時間越多。如果表中查詢的列有乙個索引,mysql能快速到達乙個...

mysql非主鍵索引 主鍵索引和非主鍵索引的區別

1.什麼是最左字首原則?以下回答全部是基於mysql的innodb引擎 例如對於下面這一張表 如果我們按照 name 欄位來建立索引的話,採用b 樹的結構,大概的索引結構如下 如果我們要進行模糊查詢,查詢name 以 張 開頭的所有人的id,即 sql 語句為 select id from tabl...