1. 程式人生 > >外來鍵該不該有索引

外來鍵該不該有索引

在資料庫中,索引的使用非常重要,恰當的使用索引可以提高資料庫訪問的效率,但是索引的不當使用則會影響效能並佔用不必要的儲存空間。

在oracle資料庫中,是否應該對外來鍵使用索引呢?這可能是很多人都有的疑問,答案是肯定的,即在一般情況下應該對外來鍵使用索引。

不過在弄清這個問題之前首先要明確一個概念,就是“外來鍵”的定義。什麼是外來鍵呢?通過下面的解釋相信你一定能夠弄明白了。

1)候選鍵: 關係中的一個屬性組,其值能唯一標識一個元組,若從該屬性組中去掉任何一個屬性,它就不具有這一性質了,這樣的屬性組稱作候選碼。
2)主鍵:當有多個候選碼時,可以選定一個作為主碼,選定的候選碼稱主鍵
3)外來鍵: 關係R中的一個屬性組,它不是R的候選碼,但它與另一個關係S的候選碼相對應,則稱這個屬性組為R的外碼或外來鍵。
舉個例子:
有兩個關係:
student(s#,sname,d#),即學生這個關係有三個屬性:學號,姓名,所在系別
dep(d#,dname),即院系有兩個屬性:系號、系名
則s#、d#是主鍵,也是各自所在關係的唯一候選鍵,d#是student的外來鍵。
參考資料:資料庫——原理、程式設計與效能

上面這段是來自百度知道中的解釋,非常清楚易懂。知道了外來鍵的概念之後,我們來解釋一下為什麼需要在oracle資料庫中對外來鍵使用索引。

在oracle資料庫中,當對父表(上面例子中的dep表)進行更新的時候,如果在子表(上面例子中的student表)中的外來鍵沒有使用索引,則在更新的過程中整個子表將被鎖定,而往往實際上並不需要鎖定整個子表,而僅僅需要鎖定子表中的幾條記錄。這樣就會大大影響資料庫訪問的併發性,甚至有可能造成死鎖的情況。

除了鎖表的問題之外,一個沒有使用索引的外來鍵在下面兩種情況下表現的也十分糟糕:

  • 當使用ON DELETE CASCADE刪除父表中的記錄時,如果在子表中的外來鍵沒有使用索引則當執行該操作時會對子表進行全表的掃描,而事實上這個全表的掃描是不需要的。更壞的情況是,如果刪除多個父表中的記錄,每刪除一條記錄則會進行一次全表掃描,可想而知,對於效能的影響是多麼的大!
  • 對於父表和子表的連線查詢,情況也是類似的。當進行這種連線查詢時,如果不對外來鍵使用索引則會發現查詢的速度大大降低。

這下你一定明白了為什麼需要在外來鍵上使用索引的重要意義了,不過你還是堅持不想使用索引的話,也可以,不過必須保證下面三種情況同時滿足:

  1. 不從父表中刪除記錄
  2. 不更新父表中的主鍵的值
  3. 一般不進行父表和子表的連線查詢

如果你覺得你可以滿足上面的全部三個條件,那麼你可以不必為外來鍵新增索引。不過一般來講,上面的三種情況很難滿足,而如果你沒有使用索引的話,那麼你將為此付出很大的代價的!