Skip to content

SequentialGuid

sdrapkin edited this page Mar 30, 2017 · 10 revisions

SequentialGuid.CreateSequentialGuid() located in TinyORM.Helpers creates a System.Guid that is greater than any GUID previously generated by this function on a current WindowsOS since that WindowsOS was started. After restarting WindowsOS, the GUIDs can start again from a higher or lower range, but they will still be globally unique.

TinyORM's sequential GUIDs have the following advantages vs. other approaches:

  • As effective as TSQL-based NEWSEQUENTIALID in avoiding GUID-based index fragmentation and page cache pollution.
  • Extremely fast. CreateSequentialGuid() CPU cost is ~1.5x of a Guid.NewGuid().
  • Provides 64 bits of cryptographically-strong entropy/randomness.
    • Google required 2+ years and 2^63 computations to find a SHA1 collision.
  • Captures creation DateTime with ~7ms precision & accuracy.
    • Creation DateTime can be extracted with SequentialGuid.ExtractDateTimeUtc(guid).
  • Works perfectly across multiple Threads, AppDomains, and Processes.
    • No synchronization costs are incurred, since all synchronization happens at the WindowsOS level.

Sequential GUIDs implemented by TinyORM avoid the main disadvantages of using GUIDs for Clustered Keys and Primary Keys, while at the same time delivering a reasonable amount of entropy at 64 bits. We believe they strike a good balance between security and performance.

for (int i = 0; i < 16; ++i)
	Console.WriteLine(Helpers.SequentialGuid.NewSequentialGuid());

Guid guid = Helpers.SequentialGuid.NewSequentialGuid();
var dt = Helpers.SequentialGuid.ExtractDateTimeUtc(guid);
Console.WriteLine(dt);
/*
97ee0724-2ebb-8472-d111-11e71274e9ac
63d605eb-bde2-c9b4-d112-11e71274e9ac
c0f98bd7-36d0-deb6-d113-11e71274e9ac
4c78424a-48d2-086b-d114-11e71274e9ac
9f797bb4-c7bc-6fb2-d115-11e71274e9ac
709a9073-6c95-4306-d116-11e71274e9ac
eee50640-bfb0-05e4-d117-11e71274e9ac
25eeb4d0-3019-1c83-d118-11e71274e9ac
fa247573-c288-ccea-d119-11e71274e9ac
36728f47-0f83-713e-d11a-11e71274e9ac
5a1de984-1dce-3501-d11b-11e71274e9ac
8a7d612b-f2bf-de95-d11c-11e71274e9ac
d60e54c1-9149-ae29-d11d-11e71274e9ac
a607fabf-b5e1-5c36-d11e-11e71274e9ac
245ad0a0-f812-185d-d11f-11e71274e9ac
c74fe883-5517-eb8f-d120-11e71274e9ac
2017-03-26 22:31:48 */

Implementation details

A sample TinyORM Sequential GUID 97ee0724-2ebb-8472-d111-11e71274e9ac is made of the following parts:

  • 97ee0724-2ebb-8472 - 64 random bits (8 bytes)
  • d111 - 16 bit atomic counter maintained by WindowsOS (2 bytes)
  • 11e71274e9ac - 48 bit timestamp, with ~7 millisecond precision & accuracy (6 bytes)

The 16 bit counter value resets with every timestamp change (ie. every ~7ms).

Clone this wiki locally