IT:AD:Guid
- See also:
Summary
Guids are actually UUID.
Guid stands for Globally Unique Identifiers.
Notes
Summary
Whether to use Globally Unique Identities (Guid)'s or not use Guids for primary keys comes up regularly.
In order to make an informed decision, here are some important notes.
Notes
RFC
- Guids are defined by RFC 4122.
- When dealing with different machines, it's important to use the same mechanism, to reduce the risk of clashes.
Types of Guids
There are various types of Guids:
Time based (Variant 2, Version 1 RFC 4122) GUIDs:
* P/Invoke UuidCreateSequential
uuidgen.exe
, passing the-x
flag
Random (Variant 2, Version 4 RFC 4122) GUIDs:
* Guid.NewGuid()
is a Variant 2, Version 4 RFC 4122 GUID (random based).
- Note that internally it P/Invokes
CoCreateGuid
which in turn invokesUuidCreate
* guidgen.exe
(in Visual Studio/Windows SDK) is a Variant 2, Version 4 RFC 4122 GUID (random based).
* uuidgen.exe
tool (in SDK) is a Variant 2, Version 4 RFC 4122 GUID (random based).
* P/Invoke UuidCreate
- note: that prior to NT
UuidCreate
was Version 1 (time-based), but you'll never have to worry about it.
Non-RFC 4122 compliant:
- SqlServer's
newsequentialid()
is reshuffled Random one. And unfortunately reshuffles the position of the Variant bit. Bummer.- No shit…MS created a non-client solution on something so damn important to stick to an RFC…
Combinations
When using GUIDs as keys in a database, you must ensure that the GUIDs are all compatible with each other.
Not compatible:
newsequentialid()
is not compatible withGuid.NewGuid
newsequentialid()
is not compatible withUuidCreateSequential
(unless you're doing byte swapping manually).
Compatible:
Guid.NewGuid
andUuidCreateSequential
are compatible with each other (since they are both RFC 4122 compliant).- Other made-up GUIDs - including “comb” GUIDs (webcite) - are not compatible with any other type of GUID.
Regarding SQL Server
Sql Server: * doesn't do as expected, and orders GUID values according to the least significant six bytes (i.e. the last six bytes of the Data4 block).
- ACiD:
- Advantages:
- Easier to use as a distributed Identity than a composite key of MachineName Guid+integer PK.
- Note that that the PK can't be an AutoIncrement anyway as you can't insert a specific remote machine's id into an AutoIncrement column.
- Disadvantages:
- Although EF6.1 can handle an server generated Guid Identity in SqlServer, can't do the same trick with Sql Server CE. Which is highly annoying when it comes to having Unit Tests use CE…
- Reason why:
- Using NEWID() can make inserts that are 30 times slower (and will growing slower) and int!
- Using SEQUENTIALID() can make it better (twice as slow as Int).
- Reasonable, but not for mobile scenarios, as SEQUENTIALID() is RFC 4122 compliant, and therefore can't work with
Guid.NewGuid()
- Damn!
- NEWSEQUENTIALID:
- “Each GUID generated by using NEWSEQUENTIALID() is unique on that computer. GUIDs generated by using NEWSEQUENTIALID() are unique across multiple computers only if the source computer has a network card.”
- “Creates a GUID that is greater than any GUID previously generated by this function on a specified computer since Windows was started. After restarting Windows, the GUID can start again from a lower range, but is still globally unique.”
- If you are willing to use P/Invoke (DON'T!), you could generate NEWSEQUENTIALID compatible guids outside of SqlServer…but this would not be available on Windows Phone or anywhere else.
- If you can't stand that idea, look at this non-P/Invoke way (treat with caution as I see no reference to using the MAC, which makes it more of a random generator):
- Doing the equivalent in net would involve:
- Although there is this to, but it looks too simple:
- NEWID and NEWSEQUENTID ids should not be mixed (see above) even if the following says it can:
Resources
* http://www.informit.com/articles/article.aspx?p=25862
- It's the algorythm used by NHibernate on SqlServer.
- It has the 4 in the right place…but doesn't have machine identity
* http://blog.stephencleary.com/2010/11/few-words-on-guids.html
* http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database * http://alexandrebrisebois.wordpress.com/2013/11/14/create-predictable-guids-for-your-windows-azure-table-storage-entities/ * http://msdn.microsoft.com/en-us/library/system.guid.aspx
* Src as to how Guid.NewGuid P/Invokes what/where:
* Speed: