網頁

2019/2/9

該用Email帳號作為主鍵 (Primary key) 嗎?

資料庫設計中,例如【使用者】或【會員】資料表,應該以Email帳號作為主鍵(Primary Key, PK)嗎?

答案是最好不要,當然要用Email作主鍵也是可以,因為牽扯到「設計」就沒有絕對的正確答案。

Email是屬自然鍵(Natural Key),又稱業務鍵(Business Key),本身具有業務上的意義,可能是唯一的,本身能做為搜尋條件。

但缺點是:

Email是字串(VARCHAR),一般Email的長度約15~30個字符,與整數(int)相比占的空間比較多,且在搜尋和排序的速度會比以整數為主鍵的情況要慢。

其他資料表欄位參考至Email的外鍵也要存成Email,佔據了更多空間。例如【會員訂單】是【會員】的子表,若Email為【會員】的主鍵,則【會員訂單】參考【會員】的主鍵為外鍵欄位。

若會員要更改Email,那所有關聯資料表中的參考欄位也要同時更改,這是非常麻煩的事。

若今天允許一個會員有兩個或以上的Email,該怎麼處理對Email的正規化?

Email有可能被重用(雖然大部分的Email服務商都不允許重新註冊已刪除的帳號)。
例如使用者John Lin原本以john@abc.com註冊了你的服務,但有一天John Lin向Email服務商主動註銷了這個Email,或太久沒用被註銷;接著另一名使用者John Wang註冊了同個John@abc.com,不幸地又用這個Email註冊了你的服務,所以第二個註冊的使用者會收到「此帳號已使用」的系統回覆而感到莫名其妙。

Email是使用者個資的敏感資料。若以Email為主鍵,則不論操作資料庫的CRUD,或前後端資料傳遞及頁面切換,或與多個系統互動時,都會以Email為參數在程式中傳遞,有資安上的疑慮。

建索引(index)的效率差且維護成本高,因為Email不是依序由小而大遞增,且索引的overhead會很大。
以MySQL InnoDB為例,InnoDB的索引有兩個,一為主索引clustered index(叢集索引),以主鍵為資料;一為第二索引secondary index,為主索引外的其他索引。第二索引除了儲存自身的鍵值外還會儲存第一索引的資料,所以如果你的主鍵是Email,第二索引占的儲存空間就會非常大。假設有一百萬筆資料,那除了主索引外還要另存一百萬個Email長度的資料。


不僅是Email,建議不應該用Natural Key為主鍵,建議改用Surrogate Key(代理鍵)為主鍵(通常是依序遞增的整數)。


參考:

沒有留言:

張貼留言