2013-03-03 40 views
15

Tôi có yêu cầu tạo các id Dài duy nhất cho cột khóa cơ sở dữ liệu chính của tôi.Cách tạo Long duy nhất bằng UUID

Tôi nghĩ tôi có thể sử dụng UUID.randomUUID(). GetMostSignificantBits() nhưng đôi khi nó tạo ra một số tiêu cực dài cũng là vấn đề đối với tôi.

Có thể tạo chỉ tích cực từ UUID không? Sẽ có hàng tỷ mục nhập vì vậy tôi muốn mỗi khóa được tạo phải là duy nhất.

+0

Tại sao bạn không sử dụng trình tự? Bạn có thể sử dụng những thứ như thế không? Hoặc UUID đây là một giải pháp mà bạn phải sử dụng? –

+0

bạn có thể giải thích thêm về chuỗi số –

+0

Bạn sử dụng DB nào? Bạn sử dụng khung công tác db nào (JDBC, Hibernate, myBatis)? – Taky

Trả lời

4

Hãy xem http://commons.apache.org/sandbox/commons-id//index.html Nó có LongGenerator có thể cung cấp cho bạn chính xác những gì bạn cần.

Ngoài ra nếu bạn đang sử dụng Hibernate sau đó bạn có thể yêu cầu nó để tạo ID cho bạn (nó có một số thuật toán bạn có thể chọn từ), trong nếu không bạn chỉ có thể có một cái nhìn tại thực hiện của họ ví dụ http://grepcode.com/file/repo1.maven.org/maven2/hibernate/hibernate/2.1.8/net/sf/hibernate/id/TableHiLoGenerator.java#TableHiLoGenerator)

+0

Điều này cũng có vẻ tốt. –

+0

LongGenerator sẽ tạo một ID tuần tự có nghĩa là nó có thể va chạm. Trong khi GUID là phổ biến duy nhất. Nó có thể đáp ứng yêu cầu của Saurabh nhưng tôi nghĩ rằng đây không phải là câu trả lời hoàn toàn chính xác – Sap

+0

Apache commons-id không có sẵn để tải xuống? Bất kỳ lựa chọn thay thế nào khác? – user12458

1

Tôi vừa mới tìm ra giải pháp này. Tôi cho thời gian đang cố gắng để hiểu các solution.It nói Java thực hiện của bông tuyết twitter. Trình tạo ID tuần tự 64 bit dựa trên thuật toán tạo ID bông tuyết twitter.

https://github.com/Predictor/javasnowflake

Bất kỳ lời đề nghị được hoan nghênh.

+0

Nhưng một lần nữa tôi thấy đồng bộ hóa công cộng String generateLongId(). Khối đồng bộ sẽ làm giảm hiệu suất trong thời gian dài, –

+1

Làm thế nào để chạy dài hoặc chạy ngắn tạo sự khác biệt trong bất kỳ sự xuống cấp hiệu năng nào do đồng bộ hóa gây ra? – user93353

+2

@SaurabhKumar Tôi rất nghi ngờ bạn sẽ gặp phải vấn đề về hiệu năng với khối đồng bộ nhỏ. Mặc dù đồng bộ hóa thường chậm hơn không phải lúc nào cũng chậm hơn so với CAS (tức là NIO của Java cũng có một cuộc nói chuyện tuyệt vời về điều này) và nó chắc chắn nhanh hơn bất kỳ trình tạo id nối tiếp cơ sở dữ liệu nào (giả sử bạn cần ID trước, cơ sở dữ liệu roundtrip ... vv). Bạn nên biết rằng cũng có một số lượng lớn các thứ khác được đồng bộ hóa trong Java (hầu hết các thùng chứa servlet làm điều đó ở đâu đó). –

3

Như những người khác đã viết, dài không có đủ không gian cho một số duy nhất. Nhưng trong nhiều trường hợp, một số có thể là duy nhất đủ để sử dụng cụ thể. Ví dụ: Dấu thời gian với độ chính xác nano giây thường đủ tốt. Để có được nó, thay đổi mili giây hiện tại 20 bit còn lại để phân bổ không gian cho nano giây và sau đó che phủ nó bằng nano giây:

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

Các nano & ~ 9223372036854251520L phần lấy nano giây hiện tại và thiết lập 44 byte đầu tiên 0, chỉ để lại 20 bit ngay mà đại diện nano giây đến một phần nghìn giây (999999 nanos) Nó cũng giống như:

nanoseconds & ~1111111111111111111111111111111111111111111100000000000000000000 

Side lưu ý: nano giây không nên được sử dụng để đại diện cho hiện tại thời gian vì điểm khởi đầu của chúng không cố định theo thời gian và vì chúng được tái chế khi chúng đạt tới mức tối đa.

Bạn có thể sử dụng bất kỳ thao tác bit nào khác. Nó thường là tốt để đưa vào tài khoản thời gian hiện tại và cái gì khác như id thread hiện tại, id quá trình, ip.

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

Tôi thích điều này vì nó không sử dụng thư viện của bên thứ ba :) – DoctorD