我目前正在开发Azure表存储应用程序。在该应用程序中,我有一个表,它将具有相对较少的插入(几千/天),并且这些实体的主键将在另一个表中使用,该表将具有数十亿行。
因此,我正在寻找一种方法来使用自动递增的整数而不是GUID作为小表中的主键(因为它将节省大量存储和插入的可伸缩性并不是真正的问题)。
有关该主题的一些讨论,例如在http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797。
但是,由于并发问题可能很难调试和发现,我对自己实现这个有点不舒服。因此,我的问题是,是否有一个经过充分测试的这个问题?
答案 0 :(得分:13)
对于每个都会在搜索中找到它的人来说,有一个更好的解决方案。 Minimal time for table lock is 15 seconds - 太可怕了。如果要创建真正可扩展的解决方案,请不要使用它。使用Etag
!
在表格中为ID创建一个实体(您甚至可以将其命名为ID或其他)。
1)阅读它。
2)增量。
3)指定了InsertOrUpdate WITH ETag
(来自读取查询)。
如果上一次操作(InsertOrUpdate
)成功,那么您将获得一个新的,唯一的,自动递增的ID。如果失败(HttpStatusCode
== 412除外),则表示其他客户端更改了它。所以,再重复1,2和3。
Read+InsertOrUpdate
的通常时间小于 200ms 。我的测试工具with source on github。
答案 1 :(得分:5)
见Josh Twist的UniqueIdGenerator class。
答案 2 :(得分:4)
我还没有实现这个,但正在努力......
您可以使用下一个ID来为一个队列设置种子,然后在需要时从队列中选择它们。
您需要保留一个表以包含添加到队列中的最大数字的值。如果你知道你不会使用大量的整数,那么每隔一段时间就可以让一个工人醒来,并确保队列中还有整数。您还可以使用一个使用过的int队列,工作人员可以检查以便密切关注使用情况。
你也可以挂起那个工人,所以当你的代码需要一个id(偶然)时队列是空的,它可能会中断工人的小睡以尽快创建更多的密钥。
如果该呼叫失败,您需要一种方法(告诉工作人员您将为他们做工作(锁定),然后让工作人员工作以获得下一个ID并解锁)
然后使用新值。
答案 3 :(得分:4)
我发现的解决方案可以防止重复的ID,并让你自动增加它
lock (lease) a blob让它充当逻辑门。
然后阅读该值。
写出递增的值
发布租约
使用app / table中的值
然后,如果您的工作人员角色在此过程中崩溃,那么您的商店中只会丢失一个ID。恕我直言,这比重复更好。
以下是史蒂夫马克思的这种方法的code sample and more information
答案 4 :(得分:3)
如果你真的需要避免guid,你是否考虑过根据日期/时间使用某些东西,然后利用分区键来最小化并发风险。
您的分区键可以是用户,年,月,日,小时等,行键可以是日期时间的其余部分,以足够小的时间跨度来控制并发。
当然,你必须以Azure中的约会价格问自己,如果避免Guid真的值得所有这些额外的努力(假设一个Guid会起作用)。