停止在你的數(shù)據(jù)庫(kù)中使用UUID
在數(shù)據(jù)庫(kù)中唯一標(biāo)識(shí)行的最常見(jiàn)方法之一是使用UUID字段。然而,這種方法帶來(lái)了需要注意的性能問(wèn)題。
本文將討論在使用UUID作為數(shù)據(jù)庫(kù)表中的鍵時(shí)可能出現(xiàn)的兩個(gè)性能問(wèn)題。
我們直接進(jìn)入正題!
什么是UUID?
UUID代表通用唯一標(biāo)識(shí)符(Universally Unique Identifier)。UUID有很多版本,但在本文中,我們將討論最流行的版本:UUIDv4。
以下是UUIDv4的一個(gè)示例:
問(wèn)題1 —— 插入性能
當(dāng)向表中插入新記錄時(shí),必須更新與主鍵相關(guān)的索引以保持最佳查詢性能。索引是使用B+樹(shù)數(shù)據(jù)結(jié)構(gòu)構(gòu)建的。
對(duì)于UUIDv4來(lái)說(shuō),重新平衡過(guò)程變得非常低效。這是因?yàn)閁UID的固有隨機(jī)性,使得保持樹(shù)的平衡變得更加困難。當(dāng)你的數(shù)據(jù)規(guī)模擴(kuò)大時(shí),需要重新平衡數(shù)百萬(wàn)個(gè)節(jié)點(diǎn),這顯著降低了使用UUID鍵的插入性能。
問(wèn)題2 —— 更高的存儲(chǔ)需求
我們考慮一個(gè)帶有自動(dòng)遞增整數(shù)鍵的UUID的大小:
自動(dòng)遞增整數(shù)每個(gè)值消耗32位,而UUID每個(gè)值消耗128位。
每行UUID的存儲(chǔ)空間是整數(shù)的4倍。
此外,大多數(shù)人以人類可讀的形式存儲(chǔ)UUID,這意味著UUID每個(gè)值可能消耗多達(dá)688位。這是整數(shù)的約20倍。
讓我們通過(guò)模擬一個(gè)現(xiàn)實(shí)的數(shù)據(jù)庫(kù)來(lái)評(píng)估UUID如何實(shí)際影響存儲(chǔ)。
我們將使用Josh Tried Coding的示例表:
這個(gè)示例使用了Neon PostgreSQL數(shù)據(jù)庫(kù)。
- 表1將包含100萬(wàn)行UUID。
- 表2將包含100萬(wàn)行自動(dòng)遞增整數(shù)。
以下是結(jié)果,讓我們逐一分析每個(gè)統(tǒng)計(jì)數(shù)據(jù):
圖片
總表大小:考慮到兩個(gè)表的大小,UUID表大約是整數(shù)表的2.3倍!
ID字段大小:?jiǎn)蝹€(gè)UUID字段需要比等效整數(shù)字段多9.3倍的存儲(chǔ)空間!
ID列大小:排除每個(gè)表中的其他屬性時(shí),UUID和整數(shù)列之間的大小差異為3.5倍!
結(jié)論
UUID是確保表中記錄唯一性的好方法。然而,這些問(wèn)題在大規(guī)模使用時(shí)尤為明顯,因此對(duì)于大多數(shù)人來(lái)說(shuō),UUID實(shí)際上不會(huì)導(dǎo)致明顯的性能下降。
盡管這些問(wèn)題在大規(guī)模使用時(shí)普遍存在,但重要的是要了解在表中使用UUID的影響,并確保數(shù)據(jù)庫(kù)設(shè)計(jì)的優(yōu)化。