There are a few requirements when you want to use a GUID as a database primary key. The main ones are:
- It is unique under all circumstances
- It hashes well, i.e. you don't want all bytes that change frequently at the end.
- It compresses well, i.e. there are some chunks that remain relatively constant.
Okay the last requirement is actually important for sending it accross a web service.
At the time of writing I could not find any information on how the System generates GUIDs so I designed an implementation that would satisfy the requirements while still being very fast.
There is an outstanding bug in the NEO GUID generator: it uses the current Process ID to maintain cross-process uniqueness, but assumes that the ID will be a number less than 2^16. This is not always the case, so if your process is assigned a large ID by Windows, GUID generation will fail. The fix is probably to either use more bits from the Process ID, or lock on some system-wide state (Named Pipes and Shared Memory, anyone?) (Added to JIRA at http://jira.codehaus.org/secure/ViewIssue.jspa?key=NEO-4)
There's also another (potential) bug - the NEO GUID generator uses a static Int64 as a sequence number, which is incremented whenever a new GUID is created. However, it only uses the first 4 bytes! It then tags the total number of seconds since <some date> to this number to get temporal uniqueness but if your app creates more than 216 GUIDs per second, they will start to cycle – Jim
Given the above bugs and Jim's description of the system's GUID generation method on the mailing list, we should probably revert to the system implementation for now. – Erik
