Sequential Guid作为Azure表存储的字符串

时间:2014-12-12 20:30:02

标签: azure-storage

我们希望在Azure中的某些表中为行键使用顺序guid。

对于Sql,我通常使用codeproject上找到的修改后的代码段。它实际上允许你将guid指定为字符串,但是它对BitConverters Endianess进行了检查,我不确定这是否会影响字符串的排序,如果它们是在不同的计算机上进行的。我可以忽略这一点,只是用一套适用于ATS的方式编写它吗?

时间戳的准确性并不重要,排序根本不重要,但只能从guid中检索创建时间。

编辑:添加了一些结果

public static class SequentialStringGuidGenerator
{
     public static Guid New()
     {
         byte[] uidBytes = Guid.NewGuid().ToByteArray();
         byte[] tickBytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
         byte[] seqBytes = new byte[uidBytes.Length];

        // Mapping A
        seqBytes[0] = tickBytes[0];
        seqBytes[1] = tickBytes[1];
        seqBytes[2] = tickBytes[2];
        seqBytes[3] = tickBytes[3];
        seqBytes[4] = tickBytes[4];
        seqBytes[5] = tickBytes[5];
        seqBytes[6] = tickBytes[6];
        seqBytes[7] = tickBytes[7];

        // Mapping B
        seqBytes[0] = tickBytes[7];
        seqBytes[1] = tickBytes[6];
        seqBytes[2] = tickBytes[5];
        seqBytes[3] = tickBytes[4];
        seqBytes[4] = tickBytes[3];
        seqBytes[5] = tickBytes[2];
        seqBytes[6] = tickBytes[1];
        seqBytes[7] = tickBytes[0];

        // Mapping C
        // EDIT - this worked and was more random
        seqBytes[0] = tickBytes[2];
        seqBytes[1] = tickBytes[3];
        seqBytes[2] = tickBytes[4];
        seqBytes[3] = tickBytes[5];
        seqBytes[4] = tickBytes[6];
        seqBytes[5] = tickBytes[7];
        seqBytes[6] = tickBytes[1];
        seqBytes[7] = tickBytes[0];

        seqBytes[8] = uidBytes[0] ...etc

        return new Guid(seqBytes);
     }
}

我将开始测试不同的方式,看看看起来有什么用,然后尝试从那里弄清楚,但是如果有人可以添加任何关键的洞察力,可能会让我感觉很棒。

编辑 - 小测试

public class Testy : TableEntity
{
    public Testy()
    {

    }

    public Testy(int index)
    {
        PartitionKey = string.Empty;
        RowKey = GuidGenerator.CreateNew().ToString();
        Index = index;
    }

    public int Index { get; set; }
}

static void Main(string[] args)
    {
        var tableClient = new CloudStorageAccount(new StorageCredentials("xxxx", "xxx"), true).CreateCloudTableClient();
        var table = tableClient.GetTableReference("testing");
        table.CreateIfNotExists();

        for (int i = 0; i < 50; i++)
        {
            Thread.Sleep(100);
            var testy = new Testy(i);
            table.Execute(TableOperation.Insert(testy));
        }
        Console.WriteLine("Press Any Key to Exit");
        Console.ReadLine();
    }
}

结果:

   Mapping A - Examples
   e4af2bbc-e463-08d1-c642-fcca3a69fe4b 12/12/2014 20:48:09 0
   e4e1ae3d-e463-08d1-7d1d-d73a3f7c984c 12/12/2014 20:48:09 1
   e5000c27-e463-08d1-5109-07ab1b32af4c 12/12/2014 20:48:09 2
   e51e910f-e463-08d1-03d9-523a291a7145 12/12/2014 20:48:09 3
   e53d3d24-e463-08d1-576b-01703c80e743 12/12/2014 20:48:10 4
   e55b9b02-e463-08d1-87bb-3ff54d28a542 12/12/2014 20:48:10 5
   e57abc38-e463-08d1-5832-bc183d909144 12/12/2014 20:48:10 6
   e598f31a-e463*08d1-894f-6e45a31c374b 12/12/2014 20:48:10 7
   e5b702dd-e463-08d1-1f8b-6a04bed83b45 12/12/2014 20:48:10 8
   e5d62413-e463-08d1-b4e4-57653b770842 12/12/2014 20:48:11 9
   e5f481f5-e463-08d1-306c-da79a3170043 12/12/2014 20:48:11 10

   Mapping B - All out of order

   Mapping C
   e4650360-08d1-6fac-d1cd-865acca03746 12/12/2014 20:56:09 200
   e4650393-08d1-f055-ea2d-a2f0698d2f4e 12/12/2014 20:56:10 201
   e46503bf-08d1-a348-8baf-b6c826a5dc49 12/12/2014 20:56:10 202
   e46503dd-08d1-8ba6-8233-774c90578d46 12/12/2014 20:56:10 203
   e46503fe-08d1-93c3-acf2-4ab50d655c46 12/12/2014 20:56:10 204
   e465042a-08d1-0d41-8632-cbbf2a0f3140 12/12/2014 20:56:10 205
   e4650448-08d1-fe9e-356e-91a01885374c 12/12/2014 20:56:11 206
   e4650467-08d1-fb4a-5e8e-34c95cece845 12/12/2014 20:56:11 207
   e4650486-08d1-54ba-655e-02259e9b8e45 12/12/2014 20:56:11 208
   e46504a6-08d1-a202-e599-344c5351264b 12/12/2014 20:56:11 209
   e46504d1-08d1-4cf5-0437-cdce734bc741 12/12/2014 20:56:12 210

看起来包括tickBytes [6]和tickBytes [7]总是生成相同的代码,这是不可取的,我将排除这一点,看看是否有帮助。

编辑2:Nvm看起来像DateTime的较大部分,当然不会在很短的时间内发生变化

1 个答案:

答案 0 :(得分:0)

只需更新最终 - 简单类,即可在ATS中生成和检索顺序guid

public static class AtsIdentityFactory
{
    public static Guid CreateSequentialId()
    {
        var uidBytes = Guid.NewGuid().ToByteArray();
        var tickBytes = BitConverter.GetBytes(DateTime.UtcNow.Ticks);
        var seqBytes = new byte[uidBytes.Length];

        seqBytes[0] = tickBytes[0];
        seqBytes[1] = tickBytes[1];
        seqBytes[2] = tickBytes[2];
        seqBytes[3] = tickBytes[3];
        seqBytes[4] = tickBytes[4];
        seqBytes[5] = tickBytes[5];
        seqBytes[6] = tickBytes[6];
        seqBytes[7] = tickBytes[7];
        seqBytes[8] = uidBytes[0];
        seqBytes[9] = uidBytes[1];
        seqBytes[10] = uidBytes[2];
        seqBytes[11] = uidBytes[3];
        seqBytes[12] = uidBytes[4];
        seqBytes[13] = uidBytes[5];
        seqBytes[14] = uidBytes[6];
        seqBytes[15] = uidBytes[7];

        return new Guid(seqBytes);
    }

    public static DateTime GetDateTime(Guid id)
    {
        var seqBytes = id.ToByteArray();
        var tickBytes = new byte[8];

        tickBytes[0] = seqBytes[0];
        tickBytes[1] = seqBytes[1];
        tickBytes[2] = seqBytes[2];
        tickBytes[3] = seqBytes[3];
        tickBytes[4] = seqBytes[4];
        tickBytes[5] = seqBytes[5];
        tickBytes[6] = seqBytes[6];
        tickBytes[7] = seqBytes[7];

        var ticks = BitConverter.ToInt64(tickBytes, 0);
        return new DateTime(ticks);
    }
}