我们希望在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的较大部分,当然不会在很短的时间内发生变化
答案 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);
}
}