2013-03-03 76 views
15

我有一個要求,爲我的數據庫主鍵列生成唯一的長ID。如何生成獨特的長使用UUID

我以爲我可以使用UUID.randomUUID()。getMostSignificantBits()但有時它產生一些負面的長也是我的問題。

是否有可能從UUID中產生正數?會有類似數十億條目,所以我希望每個生成的密鑰都必須是唯一的。

+0

你爲什麼不使用順序?你能用這樣的東西嗎?或UUID這是你必須使用的解決方案? – 2013-03-03 10:49:37

+0

你能解釋更多關於序列 – 2013-03-03 10:53:36

+0

你使用什麼數據庫?你使用什麼數據庫框架(JDBC,Hibernate,myBatis)? – Taky 2013-03-03 11:00:31

回答

4

看看http://commons.apache.org/sandbox/commons-id//index.html 它有一個LongGenerator,可以給你你需要的東西。

此外,如果你使用Hibernate,那麼你可以要求它爲您生成的ID(它有幾種算法,你可以選擇),在如果不是你可以看看他們的執行例如http://grepcode.com/file/repo1.maven.org/maven2/hibernate/hibernate/2.1.8/net/sf/hibernate/id/TableHiLoGenerator.java#TableHiLoGenerator

+0

那麼這也看起來不錯。 – 2013-03-06 08:44:18

+0

LongGenerator將創建一個順序標識,表示它可能發生衝突。而GUID是普遍獨一無二的。這可能足以滿足Saurabh的要求,但我認爲這不是一個完全正確的答案 – Sap 2014-10-09 14:48:00

+0

Apache commons-id無法下載?任何其他的選擇? – user12458 2015-01-13 15:21:48

1

我剛剛遇到這個解決方案。我暫時試圖理解這個解決方案。它說Twitter的雪花的Java實現。基於twitter雪花ID生成算法的64位序列ID生成器。

https://github.com/Predictor/javasnowflake

任何建議都歡迎。

+0

但我再次看到公共同步字符串generateLongId()。同步塊會長期降低性能, – 2013-03-03 11:41:52

+1

長期運行或短期運行如何影響由同步引起的任何性能下降? – user93353 2013-03-03 12:27:38

+2

@SaurabhKumar我非常懷疑你會遇到小同步塊的性能問題。儘管同步速度通常較慢,但並不總是慢於CAS(即Java的NIO,谷歌也有這方面的話題),而且它比任何數據庫序列號生成器(假設你需要ID之前的數據庫往返...等)都快。你應該知道還有大量的其他東西在Java中同步(大多數servlet容器在某處)。 – 2013-09-25 02:16:13

3

正如其他人寫的一樣,long沒有足夠的空間來存儲唯一的數字。但是在很多情況下,一個數字對於特定用途而言可能是獨一無二的。 例如,具有納秒精度的時間戳通常足夠好。 爲了得到它,移位當前毫秒20個比特留給爲納秒分配空間,然後與納秒覆蓋它:

(System.currentTimeMillis() << 20) | (System.nanoTime() & ~9223372036854251520L); 

納米&〜9223372036854251520L部分以當前的納秒並且將第一44個字節到0,只留下右20個比特代表納秒到一毫秒(999999毫微秒) 它是相同的:

nanoseconds & ~1111111111111111111111111111111111111111111100000000000000000000 

邊注:納秒不應該被用來表示當前的因爲他們的出發點不是及時固定的,因爲他們在達到最大值時被回收。

您可以使用任何其他位操作。考慮當前時間和其他內容通常是很好的,例如當前的線程ID,進程ID,IP。

12
UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE 
+1

我喜歡這個,因爲它不使用第三方庫:) – DoctorD 2017-06-10 19:32:39