如何在分片数据库中创建唯一的行ID?

7
在非分片数据库中,我可以使用自动递增来生成唯一的ID以引用特定行。
我想将我的数据库进行分片,比如分成12个分片。现在当我插入到特定的分片时,自动递增ID不再是唯一的。
希望听到任何人处理这个问题的经验。

以前从未听说过分片这个术语 - 感谢您将其添加到我的词汇表中。 - MrTelly
5个回答

11

几种方法

1) 给每个分片分配一个独立的ID,使用复合键。

2) 给每个分片分配一个独立的ID,并为每个分片设置ID范围。

3) 使用全局唯一标识符 - GUID。


3
使用GUID,不要担心范围和复合键。您最终会添加另一个分片或需要重新组织您的分片,并且您的编号方案将需要重构。 - Jeff Fritz
1
@Jeff:GUID确实有一个严重的缺点,它们很大。根据划分数据库的原因,这可能是一个重要因素。使用ID范围允许使用小型(32位)单字段PK,在各个数据库之间没有冲突。因此,如果数量不是问题,我同意使用GUID,但它们并不总是适当的。如果一个人不将创建DB的身份与ID关联起来,则会有所帮助。这样,数据库可以“租用”ID范围,从而消除“重构”中的问题。 - AnthonyWJones
1
个人而言,我厌恶将GUID用作键,因为您无法大喊 - 看一下记录123456,GUID是反人类的。 - MrTelly

3

我用过的两种解决这类问题的方法:

  • GUID:易于实现,但会创建更大的表和索引。
  • ID域:我是自己创造了这个术语,基本上它表示将整数类型的32(或64)位分成两部分,顶部部分表示一个域。使用的位数取决于您希望支持多少个域,以及每个域引入的记录数。在这种方法中,您为每个分片分配一个域。缺点是(就我所知),数据库不直接支持此方法,您需要自己编写ID分配代码。

请您查看以下问题:http://stackoverflow.com/questions/9237165/which-of-the-following-data-duplication-options-across-shards-is-recommended 谢谢。 - jeff musk
对于ID域解决方案,您从哪里获取ID的自增部分?您是否在生产系统中使用过这些? - Daniel Skarbek

1

1)你可以使用两行(一行表示ID,另一行表示数据库ID)

2)使用Guids


2
你的第一个选项中是不是想说两列而不是两行? - Dũng Trần Trung

0

我有同样的困惑。我想我会选择一个redis解决方案。我将使用像redis-cloud.com这样的服务来生成唯一的id。所以我仍然可以为插入到我的分片表中的每个数据使用bigint。它将是顺序的,因此不会发生页面拆分。此外,分页现在非常容易实现。它解决了友好的URL问题,因为我不想在URL中使用GUID。此外,Redis Cloud是可扩展的解决方案,非常可靠,并具有自动故障转移。

我不需要决定要拆分数据的范围,我只需对主键使用MD5哈希将数据平均分配到分片之间。对于HA,我决定使用Amazon RDS进行易于按时间点备份/还原和复制。

我认为Flickr使用相同的技术,但他们有两个生成器,一个用于奇数,另一个用于偶数。


0

将数据库保持在一致的哈希循环中会有所帮助。这样,您可以确保每个数据库只处理一组id。因此,没有两个数据库会有任何公共的id。这也解决了从系统中添加和删除数据库的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接