我决定使用 GUID 作为我的许多项目数据库表的主键。我认为这是一个很好的做法,尤其是在可扩展性、备份和恢复方面。问题是我不想使用常规 GUID 并寻找替代方法。我实际上很想知道我使用什么 Pinterest 作为主键。当您查看 URL 时,您会看到如下内容:
http://pinterest.com/pin/275001120966638272/
我更喜欢数字表示,即使它是作为字符串存储的。有没有办法实现这一目标?
此外,youtube 还使用了另一种我无法弄清楚的散列技术:
http://www.youtube.com/watch?v=kOXFLI6fd5A
这让我想起像方案一样缩短网址。
我更喜欢最短的,但我知道它不能保证是独一无二的。我首先想到做这样的事情:
DateTime dt1970 = new DateTime(1970, 1, 1);
DateTime current = DateTime.Now;
TimeSpan span = current - dt1970;
结果示例:
1350433430523.66
打印自 1970 年以来的总毫秒数,但是如果我每秒有数十万次写入会发生什么。
我主要更喜欢非 BIGINT Auto-Increment 解决方案,因为使用 3rd 方工具扩展数据库以及较少问题的备份/恢复功能可以减少很多麻烦,因为我可以在服务器之间传输数据,如果我愿意的话。
另一个 复杂的方法是针对我的应用程序定制解决方案。在数据库中,主键还将包含用户名(唯一且用户无法更改),因此我可以将名称的数值与毫秒数结合起来,这将给我一个唯一的数字字符串。由于用户不会以如此高的速度插入数据,因此保证数字 ID 是唯一的。我还可以删除最后 5 个数字并仍然获得唯一 ID,因为我假设用户最多不会以每秒 1 次以上的速度插入数据,但我可能不会这样做(你怎么看?这个想法?)
所以我请求你的帮助。我的数据假设增长非常大,每年 2TB,每秒有数万个新行。我希望 URL 看起来尽可能“友好”,并且不喜欢使用“常规”GUID。
我正在使用 ASP.NET 4.5 和 MySQL 开发我的应用程序
谢谢。
最佳答案
碰撞表
对于类似 GUID 的 YouTube,您可以看到 this回答。他们基本上保留了他们正在生成的所有随机视频 ID 的数据库表。当他们请求一个新的时,他们检查表是否有任何冲突。如果他们发现碰撞,他们会尝试生成一个新的碰撞。
长主键
您可以使用 long
(例如 275001120966638272
)作为主键,但是如果您有多个服务器生成唯一标识符,则必须以某种方式对它们进行分区或引入全局锁,因此每个服务器不会生成相同的唯一标识符。
Twitter 雪花 ID
使用 long
解决分区问题的一种方法ID's 是使用雪花 ID's。这是什么Twitter uses生成它的ID。所有生成的 ID 由以下部分组成:
保留一位额外的位以供将来使用。由于 ID 使用时间戳作为第一个组件,因此它们是时间可排序的(这对查询性能非常重要)。
Base64 编码的 GUID
您可以使用 ShortGuid编码
GUID
作为 base64 字符串。缺点是输出有点难看(例如 00amyWGct0y_ze4lIsj2Mw
)并且它区分大小写,如果您将它们小写,这可能对 URL 不利。Base32 编码的 GUID
还有
GUID
的base32编码的,你可以看到 this回答。这些比上面的 ShortGuid 稍长(例如 lt7fz44kdqlu5pt7wnyzmu4ov4
),但优点是它们可以全部小写。多重因素
我一直在考虑的一种替代方法是引入多种因素,例如如果 Pintrest 使用用户名和 ID 以获得额外的唯一性:
这里的ID
1
用户独有 some-user
并且可能是他们发表的帖子数量,即他们的下一个帖子将是 2
.您也可以将 YouTube 的方法与他们的视频 ID 一起使用,但特定于用户,这可能会导致一些短得可笑的 URL。
关于asp.net - 考虑到可扩展性和友好 URL 的 GUID 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12924226/