16

我目前正在开发Azure表存储的应用程序。在那个应用程序中,我有一个表格,插入的数据相对较少(几天/几天),而这些实体的主键将用在另一个表格中,这些表格将有数十亿行。Azure表存储上的自动增量

因此,我正在寻找一种方法来使用自动递增的整数,而不是GUID,作为小表中的主键(因为它将节省大量存储空间,插入的可伸缩性并不是问题)。

关于这个话题已经有了一些讨论,例如,在http://social.msdn.microsoft.com/Forums/en/windowsazure/thread/6b7d1ece-301b-44f1-85ab-eeb274349797

但是,由于并发性问题可能很难调试和发现,我自己实现这一点有点不舒服。因此,我的问题是,如果有一个经过充分测试的这样的推测?

+0

如果你真的担心它,SQL Azure中有一张表生成身份值? – Andrew 2009-12-08 22:36:16

+0

这是一个非常好的建议。但是这会迫使我设置我的SQL服务器,因为Azure SQL数据服务不支持标识列:http://www.shanmcarthur.net/cloud-services/design-strategies-for-Azure-and-SDS 。 – Yrlec 2009-12-08 22:41:24

回答

4

我还没有实现这个还没有,但我的工作就可以了...

你可以播种您的下一个ID来使用,那么就随手摘下队列中,当你需要他们的队列。

您需要保留一个表以包含添加到队列中的最大数字的值。如果你知道你不会使用大量的整数,你可以每隔一段时间就让一个工人醒来,并确保队列中仍然有整数。您也可以使用工作人员可以检查的用过的int队列来关注使用情况。

你也可以挂钩这个工作,所以如果你的代码需要一个id(偶然),那么如果队列是空的,它可以中断工作人员的午睡以尽快创建更多的键。

如果调用失败,你就需要一种方法来(告诉工作人员你会做的工作为他们(锁定),然后做得到一张ID和解锁的工人工作)

  1. 锁定
  2. 得到表
  3. 增量创建的最后一个键并保存
  4. 解锁

然后使用新的价值。

+1

但是,队列如何保证不会创建重复的ID?我可以从http://download.microsoft.com/download/5/2/D/52D36345-BB08-4518-A024-0AA24D47BD12/Windows%20Azure%20Queue%20-%20Dec%202008.docx了解到的是,如果工作进程在处理队列消息时失败,则消息将再次添加到队列中。因此,你需要在工人角色上做出幂等的工作。如果两个不同的工作角色使用相同的消息(即相同的ID),我不知道如何使这个幂等性。 – Yrlec 2009-12-09 14:20:02

+2

如果你只有1个创建id的woker,那么dups将被放入队列。 将ID拉出队列时,获取消息,然后在使用消息内容(id)之前删除消息。这应该确保没有id被多次使用。似乎情况更糟的情况是,你可能会失去一把钥匙,但你的独特性应该还是不错的。 – 2009-12-09 17:44:09

+0

上面的第二句话应该是:“如果你只有1个创建id的话,那么dups就不会被放入队列中......” – 2009-12-09 17:45:29

3

如果您确实需要避免使用guid,您是否考虑过使用基于日期/时间的东西,然后利用分区键来降低并发风险。

您的分区键可以是用户,年,月,日,小时等,行键可以是足够小的时间段内的其余日期时间以控制并发性。

当然,你必须问自己,以Azure约会的价格问自己,如果避免一个Guid真的值得所有这些额外的努力(假设一个Guid将会工作)。

4

的解决方案,我发现,防止重复的ID,并让您自动递增它是

  1. lock (lease) a blob,让充当一个逻辑门。

  2. 然后读取值。

  3. 写增加值

  4. 松开租赁

  5. 使用在您的应用程序/表

然后值,如果你的Worker角色是在这个过程崩溃,然后您的商店中只会缺少ID。恕我直言,这比重复更好。

这里是从史蒂夫马克思

10

这种方法对于大家谁就会发现它在寻找一个code sample and more information,有一个更好的解决方案。 Minimal time for table lock is 15 seconds - 这太糟糕了。如果您想创建真正可扩展的解决方案,请不要使用它。使用Etag

在表ID创建一个实体(你甚至可以将其命名为ID或其他)。

1)请阅读。

2)递增。

3)InsertOrUpdate WITHETag指定(来自读取查询)。

如果最后一次操作(InsertOrUpdate)成功,那么你有一个新的,独特的,自增的ID。如果失败(HttpStatusCode == 412除外),则意味着其他客户端更改了它。所以,再重复1,2和3 通常时间Read+InsertOrUpdate小于200ms的。我的测试工具with source on github

+0

好主意。 – PilotBob 2015-11-06 20:37:13

+0

如何使用EGT来保证原子操作,读取和增加? 这是一种可行的方法吗? https://docs.microsoft.com/en-gb/azure/storage/storage-table-design-guide#entity-group-transactions – 2017-07-06 08:23:55