1. 程式人生 > 程式設計 >資料庫之邏輯主鍵和業務主鍵

資料庫之邏輯主鍵和業務主鍵

定義

  • 主關鍵字(PRIMARY KEY):主鍵是表中的一個或多個欄位,它的值用於唯一地標識表中的某一條記錄。

  • 外來鍵(FOREIGN KEY):如果公共關鍵字在一個關係中是主關鍵字,那麼這個公共關鍵字被稱為另一個關係的外來鍵。由此可見,外來鍵表示了兩個關係之間的相關聯絡。以另一個關係的外來鍵作主關鍵字的表被稱為主表,具有此外來鍵的表被稱為主表的從表。外來鍵又稱作外關鍵字。

  • 聚集索引:聚集索引是指資料庫錶行中資料的物理順序與鍵值的邏輯(索引)順序相同。一個表只能有一個聚集索引,因為一個表的物理順序只有一種情況,所以,對應的聚集索引只能有一個。如果某索引不是聚集索引,則表中的行物理順序與索引順序不匹配,與非聚集索引相比,聚集索引有著更快的檢索速度。

  • 非聚集索引:非聚集索引是一種索引,該索引中索引的邏輯順序與磁碟上行的物理儲存順序不同。

  • 自動編號列和識別符號列:對於每個表,均可建立一個包含系統生成的序號值的識別符號列,該序號值以唯一方式標識表中的每一行。

  • 業務主鍵(自然主鍵):在資料庫表中把具有業務邏輯含義的欄位作為主鍵,稱為“自然主鍵(Natural Key)”。

  • 邏輯主鍵(代理主鍵):在資料庫表中採用一個與當前表中邏輯資訊無關的欄位作為其主鍵,稱為“代理主鍵”。

  • 複合主鍵(聯合主鍵):通過兩個或者多個欄位的組合作為主鍵

使用邏輯主鍵原因

業務變化

  • 使用邏輯主鍵的主要原因是:業務主鍵一旦改變則系統中關聯該主鍵部分的修改將會是不可避免的,並且引用越多改動越大。而使用邏輯主鍵則需要修改主鍵相關的業務邏輯即可,減少了業務主鍵相關改變對系統的影響。業務邏輯的改變是不可避免的,因為“永遠不變是變化”,沒有任何一個公司是一成不變的,沒有任何一個業務是永遠不變的。最典型的例子就是身份證升位和駕駛執照號換用身份證號的業務變更。而且現實中也確實出現了身份證號碼重複的情況,這樣如果用身份證號碼作為主鍵也帶來了難以處理的情況。當然應對改變,可以又很多解決方案,方案一是做一個新的系統與時俱進,這對軟體公司說確實是好事。

主鍵過大不利於傳輸、處理和儲存

  • 使用邏輯主鍵的另外一個原因是,業務主鍵過大,不利於傳輸、處理和儲存。我認為一般如果業務主鍵超過8位元組就應該考慮使用邏輯主鍵了,因為int是4位元組的,bigint是8位元組的,而業務主鍵一般是字串,同樣是 8 位元組的 bigint 和 8 位元組的字串在傳輸和處理上自然是 bigint 效率更高一些。想象一下 code == "12345678" 和 id == 12345678 的彙編碼的不同就知道了。當然邏輯主鍵不一定是 int 或者 bigint ,而業務主鍵也不一定是字串也可以是 int 或 datetime 等型別,同時傳輸的也不一定就是主鍵,這個就要具體分析了,但是原理類似,這裡只是討論通常情況。同時如果其他表需要引用該主鍵的話,也需要儲存該主鍵,那麼這個儲存空間的開銷也是不一樣的。而且這些表的這個引用欄位通常就是外來鍵,或者通常也會建索引方便查詢,這樣也會造成儲存空間的開銷的不同,這也是需要具體分析的。
  • 使用邏輯主鍵的再一個原因是,使用 int 或者 bigint 作為外來鍵進行聯接查詢,效能會比以字串作為外來鍵進行聯接查詢快。原理和上面的類似,這裡不再重複。

人為因素

  • 使用邏輯主鍵的再一個原因是,存在使用者或維護人員誤錄入資料到業務主鍵中的問題。例如錯把 RMB 錄入為 RXB ,相關的引用都是引用了錯誤的資料,一旦需要修改則非常麻煩。如果使用邏輯主鍵則問題很好解決,如果使用業務主鍵則會影響到其他表的外來鍵資料,當然也可以通過級聯更新方式解決,但是不是所有都能級聯得了的。

使用業務主鍵的原因

  • 使用業務主鍵的主要原因是,增加邏輯主鍵就是增加了一個業務無關的欄位,而使用者通常都是對於業務相關的欄位進行查詢(比如員工的工號,書本的 ISBN No. ),這樣我們除了為邏輯主鍵加索引,還必須為這些業務欄位加索引,這樣資料庫的效能就會下降,而且也增加了儲存空間的開銷。所以對於業務上確實不常改變的基礎資料而言,使用業務主鍵不失是一個比較好的選擇。另一方面,對於基礎資料而言,一般的增、刪、改都比較少,所以這部分的開銷也不會太多,而如果這時候對於業務邏輯的改變有擔憂的話,也是可以考慮使用邏輯主鍵的,這就需要具體問題具體分析了。

安全問題

  • 使用業務主鍵的再一個原因是,對於銀行系統而言安全性比效能更加重要,這時候就會考慮使用業務主鍵,既可以作為主鍵也可以作為冗餘資料,避免因為使用邏輯主鍵帶來的關聯丟失問題。如果由於某種原因導致主表和子表關聯關係丟失的話,銀行可是會面臨無法挽回的損失的。為了杜絕這種情況的發生,業務主鍵需要在重要的表中有冗餘存在,這種情況最好的處理方式就是直接使用業務主鍵了。例如身份證號、存摺號、卡號等。所以通常銀行系統都要求使用業務主鍵,這個需求並不是出於效能的考慮而是出於安全性的考慮。
  • 使用業務主鍵的另外一個原因是,對於使用者操作而言,都是通過業務欄位進行的,所以在這些情況下,如果使用邏輯主鍵的話,必須要多做一次對映轉換的動作。我認為這種擔心是多餘的,直接使用業務主鍵查詢就能得到結果,根本不用管邏輯主鍵,除非業務主鍵本身就不唯一。另外,如果在設計的時候就考慮使用邏輯主鍵的話,編碼的時候也是會以主鍵為主進行處理的,在系統內部傳輸、處理和儲存都是相同的主鍵,不存在轉換問題。除非現有系統是使用業務主鍵,要把現有系統改成使用邏輯主鍵,這種情況才會存在轉換問題。暫時沒有想到還有什麼場景是存在這樣的轉換的。
  • 使用業務主鍵的再一個原因是,對於銀行系統而言安全性比效能更加重要,這時候就會考慮使用業務主鍵,既可以作為主鍵也可以作為冗餘資料,避免因為使用邏輯主鍵帶來的關聯丟失問題。如果由於某種原因導致主表和子表關聯關係丟失的話,銀行可是會面臨無法挽回的損失的。為了杜絕這種情況的發生,業務主鍵需要在重要的表中有冗餘存在,這種情況最好的處理方式就是直接使用業務主鍵了。例如身份證號、存摺號、卡號等。所以通常銀行系統都要求使用業務主鍵,這個需求並不是出於效能的考慮而是出於安全性的考慮。
  • 使用複合主鍵的主要原因和使用業務主鍵是相關的,通常業務主鍵只使用一個欄位不能解決問題,那就只能使用多個欄位了。例如使用姓名欄位不夠用了,再加個生日欄位。這種使用複合主鍵方式效率非常低,主要原因和上面對於較大的業務主鍵的情況類似。另外如果其他表要與該表關聯則需要引用複合主鍵的所有欄位,這就不單純是效能問題了,還有儲存空間的問題了,當然你也可以認為這是合理的資料冗餘,方便查詢,但是感覺有點得不償失。
  • 使用複合主鍵的另外一個原因是,對於關係表來說必須關聯兩個實體表的主鍵,才能表示它們之間的關係,那麼可以把這兩個主鍵聯合組成複合主鍵即可。如果兩個實體存在多個關係,可以再加一個順序欄位聯合組成複合主鍵,但是這樣就會引入業務主鍵的弊端。當然也可以另外對這個關係表新增一個邏輯主鍵,避免了業務主鍵的弊端,同時也方便其他表對它的引用。
  • 綜合來說,網上大多數人是傾向於用邏輯主鍵的,而對於實體表用複合主鍵方式的應該沒有多少人認同。支援業務主鍵的人通常有種誤解,認為邏輯主鍵必須對使用者來說有意義,其實邏輯主鍵只是系統內部使用的,對使用者來說是無需知道的。

結論或推論:

1、儘量避免使用業務主鍵,儘量使用邏輯主鍵。

2、如果要使用業務主鍵必須保證業務主鍵相關的業務邏輯改變的概率為0,並且業務主鍵不太大,並且業務主鍵不能交由使用者修改。

3、除關係表外,儘量不使用複合主鍵。