2013-10-14 149 views
0

最近我寫了一個小程序,沒什麼值得注意的,主要是爲了測試一些我發現的新東西,那些東西實際上並不適合當時的任何實際應用。其中一件事就是使用UUID而不是序列生成(通過底層的Oracle數據庫)爲我的Hibernate實體生成ID。使用UUID作爲Hibernate主鍵ids被認爲是不好的設計?

我的一位同事認爲這將是不好的設計,可能對系統本身(即數據庫沒有提供ID,即失去控制權)或性能(不生成UUID)產生負面影響,但在數據庫端,處理它們)。有沒有支持這一說法的要點呢,還是它是超大型的?我的意思是,生成器是由Hibernate提供的,並不像有人一定認爲它是一個好主意,擺脫序列似乎是一個很好的折衷,並不是說它們不好,更多的是他們感覺像開銷一樣。

回答

0

一個UIID是INTEGER(11)大小的許多倍,而這一點對性能會產生重大影響。我沒有看到任何理由而不是使用已經內置到數據庫中的設施。這是真的,你必須爲該課程辯解,而不是你的同事相反。

1

究竟不使用數據庫生成主鍵可能是使用UUID的理由:你可以部署應用程序的多個實例,並在本地生成的ID,而不需要一個全球性的協調。 使用全局協調器可能會降低您的可伸縮性。

如果你批量插入的UUID可能是一個性能問題,因爲它們被均勻分佈在密鑰空間,導致許多可能尋求以確保關鍵是唯一的。

根據您的數據庫,你應該考慮調整其關於UUID:Postgres有一個UUID列,在MySQL中你可能想將其表示爲二進制避免UTF8開銷。

的UUID一個額外的好處:如果你暴露的ID給前端/最終用戶,他看不出有多少個對象在數據庫中,也沒有猜到下一個ID。

2

如果您不喜歡序列(並且存在使用它們的缺點,例如跨實例的可移植性),那麼爲什麼不使用Oracle的GUID呢?它可用於自動生成主鍵也:

create table my_tab2 
(
val1 raw(16) default sys_guid(), 
val2 varchar2(100), 
primary key(val1) 
) 
table MY_TAB2 created. 
> insert into my_tab2 (val2) values ('A test val') 
1 rows inserted. 
> commit 
committed. 
> select * from my_tab2 
VAL1        VAL2                        
-------------------------------- ---------------------------------------------------------------------------------------------------- 
E8B47FA523673C97E040A8C014175791 A test val 

你甚至不必關心PK的填充方式(對於一個序列中沒有觸發或不斷地在插入使用seq.nextval)。看起來不是很漂亮(我猜想數字不是很好)。另外,如果你依賴於Hibernate(或者數據庫之外的任何其他應用程序/系統)來爲表生成密鑰,那麼該表就是100%依賴於Hibernate或任何外部系統的持續維護和完整性。數據屬於公司,而不是應用程序。在我看來,數據庫層應該儘可能獨立(在這種情況下,只需使用Oracle的sys_guid而不是Hibernate生成的內容,可以增加數據層的獨立性)。在這種情況下可能看起來微不足道,但爲什麼不使用Oracle首先提供的功能。

相關問題