分片数据库的ID生成(Azure联合数据库)

时间:2012-02-16 22:35:47

标签: .net azure azure-sql-database sharding

我一直在寻找关于Azure联合数据库的id生成(针对联合/主键)的最佳实践的一些文章或指南,并且没有发现任何引人注目的内容。联合表不支持标识列,因此在我看来,唯一实用的id类型是GUID,因为尝试集中创建和使用BigInt会在应用程序中创建单点故障。我主要担心的是使用GUID而不是BigInts的性能影响(特别是对表的索引)。

是否有任何建议/最佳实践(或现有库)为分布式系统创建独特的BigInts(或者我不应该担心使用GUID的性能影响吗?)。

[更新]

自从发布问题以来已经阅读了很多关于此问题的内容,在我看来,密钥生成将成为Azure中的一个问题。根据Microsoft的此blog帖子,建议将GUID用作联合密钥。但是,他们没有提到Federated表上的所有索引(包括聚簇索引)都必须包含联合密钥。这意味着所有这些索引都将包含GUID,这将破坏插入性能。

替代方案似乎是使用中心密钥生成服务(如下面Simon所述),它在潜在的瓶颈和中心故障点方面有其自身的缺点。

我原本以为微软会对此提出更多指导,因为这是每个创建联合表的人都会遇到的问题!

总的来说,我决定采用集中式密钥生成服务,但它确实让我感到担忧。如果有人有一些神奇的技巧,我很乐意听到它(或者如果我遗漏了一些明显的东西,请告诉我)!

4 个答案:

答案 0 :(得分:4)

您可以使用各种技术在应用程序中创建序列,但由于分布式特性,它们并不简单。一个非常好的是使用blob storage and preconditions

根据您的项目计划,您可能希望使用SQL 2012 SEQUENCE并将所有序列放在一个小的非联合数据库中。 SQL Azure上没有的SEQUENCE。

答案 1 :(得分:2)

当您考虑联合密钥时,考虑一个实际上会在联合成员之间进行良好分发的密钥非常重要,因此在许多情况下生成的ID不是一个好主意。 例如 - 对订单ID进行分区将意味着所有最新订单都在最新的联合成员中,并且可能是大多数用户正在执行的操作,因此联盟的好处将大大减少,对国家/客户ID进行分区/ etc更有可能实现联邦旨在带来的可扩展性优势。

当涉及到行的唯一身份时,您需要考虑实体将存储在不同的数据库中,因此无法获得身份或序列生成,请查看Cihan Biyikoglu blog post on this - 他的建议是使用uniqueidentifier或datetimeoffset

答案 2 :(得分:1)

在我的项目中,我总是使用GUID作为联合密钥,因为我认为它不会导致大量的性能问题。也许我的项目不是那么大,但它对我有用。所以我对你的第一个问题的回答是'是'。

你的下一个问题,我正在考虑在那里有一个ID Generator服务,就像你想的那样,但是它可能是一个瓶颈。我在想是否可以拥有一个ID池,它利用一些分发缓存来存储该服务生成的ID。因此,任何人都希望使用它从池中检索的ID,而不是按需生成。因此,ID Generator将继续推送该池中的ID,消费者将从中弹出ID。这可能会有所帮助,但同样,我从未以这种方式实施,所以我可能无法说这是否是最佳实践。

希望这有帮助。

答案 3 :(得分:0)

使用GUID作为主键的一个不利之处是,如果表在主键上聚集,则会在插入时导致大量页面拆分。这是因为良好的GUID不是按时间顺序生成的,因此难以猜测。

Azure SQL表执行需要聚簇索引。我的建议是在基于范围的值(如datetime)上使用聚簇索引,并对主键使用非聚集索引,这将是GUID。