用户的唯一标识符

问题描述:

如果我通常有一百个用户的表,我只需将自动增加的userID列设置为主键。但是,如果突然我们有一百万用户或五百万用户,那么这变得非常困难,因为我希望开始变得更加分散,在这种情况下,自动递增主键将是无用的,因为每个节点将创建相同的主键。用户的唯一标识符

解决方案是使用自然主键?我真的很难为这群用户想到一个自然的主键。问题是他们都是年轻人,所以他们没有国民保险号码或任何其他我能想到的独特标识符。我可以创建一个多列主键,但是仍然有机会,但是很少发生重复。

有谁知道解决方案吗?

谢谢

我会说暂时保持用户ID的自动增量。

当你确实有数百万用户的突然匆忙时,那么你可以考虑改变它。

换句话说,解决问题时,你有它。 “过早优化是万恶之源。”

要回答这个问题 - 某些自动增量将允许您对自动增量进行播种,这样您可以在不同节点上获得不同的自动增量。这将避免该问题,同时仍允许使用自动增量。

+7

虽然我不像任何人那样过早/不必要地进行优化,但我更**反对改变正在使用的表上的主键。 – 2010-04-08 18:22:35

+0

@Adam Robinson - 我完全同意。但是,对于某些问题,还需要现实一些。 – Oded 2010-04-08 18:27:44

+0

我同意亚当。如果我认为克里斯托弗将要经历身份领域的问题,我可能会投票赞成。 – 2010-04-08 18:44:01

这里的标准解决方案是使用GUID。尽管如此,它们在索引方面表现不佳。

+2

正如你可能知道,您可以通过更换一半或GUID与一个DateTime四分之一牺牲了一些GUID的唯一性。我相信这被称为COMB指导。索引性能非常接近int值。也就是说,GUID将在页面中消耗更多空间并导致更多分裂。 – Thomas 2010-04-08 18:29:43

+1

当你达到500万用户时,你不需要你可以获得的每一点表现吗?你会浪费缓存内存索引长GUID在这个表和许多FKs它。 – 2010-04-08 18:47:07

不要使用自然主键,除非您想要糟糕的性能和不良数据的可能性。有很少的自然钥匙可能随着时间而改变,特别是名字。如果自然键发生改变,则所有相关的子记录也必须改变。这显然是不好的。

您可以使用GUIDS。但在数据方面500万是没有用的,并且可能不需要改变。我们的系统中有超过10,000,000个不同的人,我们只有一个中等大小的数据库,没有分区或需要GUID。

GUID是一个简单的方法,但...

如何分配它需要是什么?如果是有限数量的数据库,则可以为每个数据库提供一系列要使用的数字。因此,例如第一数据库自动生成范围0号999,999和下使用1,000,000 1,999,999。这样他们可以生成一个用户ID而不会相互碰撞。如果数据库包含一个唯一的数字来标识它,那么范围可以从这个数字中自动生成。

我不认为你可以使用自动增量列这样做,但存储的过程可能会产生这样的数字。

GUID很好,但会发生碰撞(虽然很少见)。

这可能是一个非标准的解决方案,但我会扔出来有:

您可以使用自动递增的数字,但根据在未来发行分离numberspace。

假设你有3台服务器。记录的ID,如下所示:

服务器1:0 - 9999999
服务器2:1000 - 19999999
服务器3:20000000 - 29999999

即使在一个32位int的约束,这应该离开大量的扩展空间(如果你担心的话,甚至可以使用100,000,000的空缺),并且它基本上保证了整个系统的独特性。

GUID在群集时是垃圾密钥。如果不是群集,您仍然需要在另一列上使用聚簇索引。

使用的整数密钥和用于每个new节点/站点

  • 增量中的10步骤当添加节点,刚开始在2,3等
  • 使用范围例如1->百万,1000000 - > 1999999等
  • 别忘了 - 也是。例如,您可以为第二个节点

如果你有节点/站点然后用SITEID第二列将工作太(-1 -1)具有同一性。

+1

当然,downvoter知道所有GUID是优越的...? – gbn 2010-04-08 18:40:49

,如果你需要数以百万计的ID,并有许多节点,使主键的复合材料:

NodeID int --unique for each node 2 or 4 byte 
UserID int --auto increment 8 byte, repeats for each node 

这是远远比一个GUID更好(更小,占用更少的内存,并会更快)

如果您使用的是MSSQL,则可以将您的表的PK创建为UNIQUEIDENTIFIER,并将默认值或绑定设置为NEWID()。

我建议你永远不要考虑GUID的一个原因是,目前我有麻烦与他们假设,如果你有数百万用户,那么你可能需要更大程度的并发性和GUID会毁了你的生活,同时插入和删除,因为你将有一个索引在他们和默认情况下,它将是一个聚集索引,这意味着当你有一个聚集索引每插入和删除将物理移动记录,而且GUID是不连续的,因此将有一个零的机会,每个新的插入在页面底部或顶部。所以整体插入和删除操作将变得非常昂贵,并且如果您删除索引,那么您的选择将变得昂贵。

特别是如果你有多个表,并且它们之间有关系,那么就不要把Guid看作主键。

有以下两种解决方案,我会推荐。

  1. 如果你能组合键,这将是完美的一样,如果它的银行软件则可能是branchId,transactionId的将成为主键,其中branchId是插入记录的节点的身份和transactionId的是自动NUM在分店,所以你会一路获得唯一性。

  2. 如果上面不是你喜欢做的或考虑那么你可以使用Guid作为一个独特的字段,但添加一个自动递增数字作为主键,这将帮助你降低总成本,如客户端(节点)发送使用(网络服务),RPC,那么你必须要插入记录到服务器的数据库中,然后将生成一个自动编号数据和该自动编号可用于未来的选择,删除或更新,但客户不必须知道关于这个自动编号

我明白,第二个解决方案有点混乱和复杂,但它仍然比使用Guids作为PK更好。但是如果解决方案1适用的话。

当我说成本不仅是处理时间,而且它的锁(等待)时间,这完全是浪费金钱,你的四核服务器可能会执行一半,而更多的锁意味着更多的死锁机会所以我的朋友从不使用Guids。

问候 Mubashar