用户的唯一标识符

时间:2010-04-08 18:15:33

标签: sql primary-key natural-key

如果我有一百个用户的表,我会设置一个自动增加的userID列作为主键。但是,如果突然我们有一百万用户或500万用户,那么这变得非常困难,因为我希望开始变得更加分散,在这种情况下,自动增量主键将是无用的,因为每个节点将创建相同的主键。 / p>

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

有谁知道解决方案?

由于

9 个答案:

答案 0 :(得分:11)

我想说暂时保留用户ID的自动增量。

如果你确实有数百万用户突然涌入,那么你可以考虑改变它。

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

要回答这个问题 - 一些自动增量将允许您为自动增量设定种子,因此您可以在不同的节点上获得不同的自动增量。这样可以避免这个问题,同时仍允许使用自动增量。

答案 1 :(得分:8)

此处的标准解决方案是使用GUID。但是,它们在索引方面表现不佳。

答案 2 :(得分:2)

GUID很好,但可能会发生碰撞(尽管很少见)。

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

您可以使用自动递增数字,但可以根据将来的分布来区分数字空间。

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

服务器1:0 - 9,999,999
服务器2:10,000,000 - 19,999,999
服务器3:20,000,000 - 29,999,999

即使在32位int的约束下,也应该留下足够的扩展空间(如果你担心的话,甚至可以使用100,000,000的差距),它基本上保证了系统的唯一性。

答案 3 :(得分:2)

如果您需要数百万个ID并且拥有许多节点,请将主键组合为:

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

这比GUID更好(更小,使用更少的内存,并且会更快)

答案 4 :(得分:1)

除非您想要糟糕的性能和可能存在错误数据,否则切勿使用自然主键。很少有自然键可以随着时间的推移而变化,特别是名称。如果自然键发生更改,则所有相关的子记录也必须更改。这显然很糟糕。

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

答案 5 :(得分:0)

GUID是一个简单的出路,但......

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

我认为您不能使用自动增量列来执行此操作,但存储过程可以以这种方式生成数字。

答案 6 :(得分:0)

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

使用整数键和每个new节点/站点

  • 增加步数10.当您添加节点时,只需从2,3等开始
  • 使用范围,例如1-> 1000000,1000000 - > 1999999等
  • 不要忘记 - 也是。例如,您可以为第二个节点
  • 设置IDENTITY(-1,-1)

如果您有节点/站点,那么带有SiteID的第二列也将起作用。

答案 7 :(得分:0)

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

答案 8 :(得分:0)

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

特别是如果您有多个表并且它们之间存在关系,则不要将Guids视为主键。

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

  1. 如果您可以制作完美的复合键,就像它的银行软件可能是branchId一样,transactionId将成为主键,其中branchId是插入记录的节点的标识,transactionId是自动数字分支,这样你就可以获得独特性。

  2. 如果您不喜欢上述或考虑上述内容,那么您可以将Guid用作唯一字段但添加自动增量编号作为主键,这将有助于您降低总体成本,例如客户端(节点) )使用(Web服务)RPC发送数据然后您必须将记录插入服务器数据库然后将生成自动编号,并且此自动编号可用于将来的选择,删除或更新,但客户端不必知道此自动编号

  3. 我知道第二种解决方案有点令人困惑和复杂,但它仍然比使用Guids作为PK更好。但如果解决方案1适用,那就去吧。

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

    此致 Mubashar