Giter Site home page Giter Site logo

mareek / uuidnext Goto Github PK

View Code? Open in Web Editor NEW
152.0 9.0 10.0 312 KB

A fast and modern .NET library to generate UUID/GUID that are either sequential and database friendly (versions 7), name based (versions 5) or random (version 4).

License: BSD Zero Clause License

C# 99.07% Smalltalk 0.93%
uuid guid

uuidnext's Introduction

UUIDNext

A fast and modern .NET library to generate UUID/GUID that are either sequential and database friendly (versions 7 & 8), name based (versions 5) or random (version 4).

How to Install

UUIDNext is available on nuget.org

How to Use

using System;
using UUIDNext;

// Creating a database friendly UUID (version 7)
Guid sequentialUuid = Uuid.NewDatabaseFriendly(Database.SQLite);
Console.WriteLine($"This is a database friendly UUID : {sequentialUuid}");



// Creating a name based UUID (Version 5)
Guid urlNamespaceId = Guid.Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8");
Guid nameBasedUuid = Uuid.NewNameBased(urlNamespaceId, "https://github.com/uuid6/uuid6-ietf-draft");
Console.WriteLine($"This is a name based UUID : {nameBasedUuid}");

What are all these versions ? I didn't know there were so many types of GUID

The traditional GUID (a.k.a UUID Version 4) is fine and works really well for it's intended use. But its random nature is problematic in some scenarios that's why other UUID versions have been created.

UUID Version 3 and 5 are name-based UUIDs. They take a namespace and a name as input and produce a hash-like UUID. Usage of Version 3 is discouraged as it is based on the obsolete MD5 hash function.

UUID Version 7 and 8 are intended to be used as a primary key in a database. The randomness of UUID V4 has a negative impact on performance when used as a key in a database and UUID V1 exposed the MAC address of the machine where it was created. UUID V7 & 8 aims to take the best of both worlds without their drawbacks. They are currently at the draft stage so their structure and implementation may change.

Why creating a new Library ? is there a problem with Guid.NewGuid() ?

As I said, UUIDs V4 produced by Guid.NewGuid() are fine when they are not used in the scenarios described above and there's no reason to stop using them. But if you find yourself in a position where UUID V4 is suboptimal, this library is for you.

Resources

RFC 4122 : The original standard for UUID Version 1 to 5.

Draft new UUID RFC : The proposed updated standard that include UUID Version 6 to 8

uuidnext's People

Contributors

mareek avatar notilya4 avatar zireael-n avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uuidnext's Issues

Is UUIDv7 adding milliseconds correctly?

The source code for UUIDv7 places the ms value (0-999) in the lower 12 bits (0-4095) of bytes 5 and 6:

        private void SetTimestampMs(Span<byte> bytes, TimeSpan unixTimeStamp)
        {
            short timestampMs = (short)unixTimeStamp.Milliseconds;
            Span<byte> timestampMsBytes = stackalloc byte[2];
            BinaryPrimitives.TryWriteInt16BigEndian(timestampMsBytes, timestampMs);
            // this byte is shared with the last 4 bits of the timestamp.
            // as the 6 upper bits of the milliseconds will alaways be 0 we can simply add the two bytes
            bytes[0] |= timestampMsBytes[0];
            bytes[1] = timestampMsBytes[1];
        }

Doesn't this mean the timestamps implied by UUIDNext's UUIIDv7 will be parsed as having fractional seconds ranging from x.000... secs to x.000244 secs (=999/4096), and then in the next millisecond jump to (x+1).000... secs? i.e. leaving a gap of 756us.

The proposed UUIDv7 spec says at L858 of https://github.com/uuid6/uuid6-ietf-draft/blob/master/draft-peabody-dispatch-new-uuid-format-02.txt:

   To perform the sub-second math, simply take the first (most
   significant/leftmost) N bits of subsec and divide it by 2^N.  Take
   for example:

   1.  To parse the first 16 bits, extract that value as an integer and
       divide it by 65536 (2 to the 16th).

   2.  If these 16 bits are 0101 0101 0101 0101, then treating that as
       an integer gives 0x5555 or 21845 in decimal, and dividing by
       65536 gives 0.3333282

   This sub-second encoding scheme provides maximum interoperability
   across systems where different levels of time precision are
   required/feasible/available.  The timestamp value derived from a
   UUIDv7 value SHOULD be "as close to the correct value as possible"
   when parsed, even across disparate systems.

In your case, the subsecond value comes from unixTimeStamp.Milliseconds rather than being a binary fraction. So I think you should multiply the number of ms by 4096 and take the remainder module 1000.

Improve library "ergonomics"

Following the discussion in #5 , I will limit the public surface of the API and add more comments for developers that want to dig further than the few methods in the Uuid static class.

  • make all generators internal as they are not meant to be used directly (or maybe just their constructors ?)
  • remove non used generators (V3 and V6)
  • add some comments in UuidV8SqlServerGenerator to explain the reasons of this implementation (see #2)

Is toByteArray outputting the correct format?

If I understood correctly, GUID type is low endian, and UUIDv7 spec is big endian which means that toByteArray() will be wrong for NewDatabaseFriendly(Database.SQLite), but not for NewDatabaseFriendly(Database.SqlServer) which is UUIDv8 LE. Is that correct? If so, maybe there should be a disclaimer somewhere in the readme.

Also, is it possible to make all UUIDs represented correctly once dotnet/runtime#87993 is merged, probably for NET8?

Love the repo, but.

Some developers will need to run the licence past key stakeholders in thier company, some (snowflakes) of which might be offended by what they read.

UUIDs are not sorted properly in a MSSQL DB at scale

Context is here Link to code that can be reproduced

Using UUID version 7:

var values = Enumerable.Range(1, 10)
.Select(i => {
Thread.Sleep(TimeSpan.FromMilliseconds(10)); // UUIDNext uses millisecond-precision, let's sleep for a bit
return $"({i}, '{Uuid.NewDatabaseFriendly():D}')";
})
.ToList();

Console.WriteLine($"{string.Join(", ", values)}");

Then check that ORDER BY sorts them as expected:

CREATE TABLE #testing_uuids (
ExpectedPosition int PRIMARY KEY,
UUID uniqueidentifier NOT NULL
);

INSERT INTO #testing_uuids
VALUES (1, '01855978-effc-758f-8fc1-6b755429799c'),
(2, '01855978-f00f-74c2-a6f0-8e8c5445ec9a'),
(3, '01855978-f019-7104-bab4-79f068bc8150');

SELECT *
FROM #testing_uuids
ORDER BY UUID ASC;

Unfortunately, on MSSQL I got 1, 3, 2.

New license suggestion

Hi, your project is really nice and I would like to use this at our company but the current license choice may not be perceived as the most professional option.

Would it be possible to use a more commonly used open-source project license like MIT ?

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.