为什么ASP.NET Identity 2.0使用GUID /字符串作为用户ID?

正如标题所说,我想知道,为什么ASP.NET Identity 2.0使用带有GUID的字符串作为用户表的主要群集密钥。 这对整数id有什么好处吗? 我只看到问题,GUID不是聚簇索引的最佳选择。

我错过了什么或整数仍然是更好的选择吗?

关于guid的使用,有一种观点认为,为了将标识符与其周围的数据完全分开,促使使用没有“含义”的id; 从数据存储区外部看不到此ID。 如果我们看一下代理键的某些特征,我们有以下内容

  • 该值在系统范围内是唯一的,因此永远不会重复使用
  • 该值是系统生成的
  • 该值不可由用户或应用程序操纵
  • 该值不包含语义含义
  • 该值对用户或应用程序不可见
  • 该值不是由来自不同域的多个值组成。

因此,guid符合该法案,因为它确实是由系统生成的,并且与域无关。 我认为使用guid主要是这种特殊思维方式的趋势问题; 但是,由于它们引入了一种新的“可扩展主键”机制,因此可以更改密钥,因此您可以使用PK的整数进行回退 。


关于性能,我会指出你接受的答案是:

GUID似乎是您主键的自然选择 – 如果您真的必须,您可能会争辩将其用于表的PRIMARY KEY。 我强烈建议不要使用GUID列作为群集密钥,默认情况下SQL Server会执行此操作,除非您明确告知不要这样做。

你真的需要分开两个问题:

  • 主键是一个逻辑构造 – 唯一且可靠地标识表中每一行的候选键之一。 这可以是任何东西,真的 – 一个INT,一个GUID,一个字符串 – 选择对你的场景最有意义的东西。
  • 集群密钥(在表上定义“聚集索引”的一列或多列) – 这是一个与物理存储相关的东西,在这里,一个小的,稳定的,不断增加的数据类型是你最好的选择 – INT或BIGINT作为您的默认选项。

这完全证实了你的印象。

其他答案非常好,但是我没有看到的一个优点是Guid.NewGuid() (理论上)创建了一个唯一的ID而没有将行提交到数据库。

基于整数的标识列需要数据库刷新才能获取其ID。 在某些情况下,在代码中生成行的PK并将其传递给数据库是很有用的(显然,还有其他方法可以通过唯一约束实现此目的,但Guid是一个相当不错的选择)。

我假设“to id”是指顺序整数ID,因为UUID毕竟是一个ID。

如果绝对没有人使用Identity 2.0或未来版本,想要合并,或组合多个商店,或者曾经导入用户和/或rôles,那么数字ID就可以工作。

如果只有少数人做,甚至可能,那么UUID会更有意义。

有一个论点是使用自然键,例如用户名,其优点和缺点一般都是经过深入探索的。 IIRC,他们确实是第一次这样做。

总之,UUID似乎是一个明显的选择。

Guid作为UserId(因此主键)有时可能是你最好的朋友。

当人们对GUID“咆哮”时要考虑的事情是他们可能没有考虑“偶尔连接”的应用程序,在这种应用程序中,您无法访问数据库以获取“int”身份字段值,直到您重新连接但需要创建多个记录表离线链接在一起。 拥有Guid允许应用程序创建“用户”,因此“userId”作为主键,在您重新联机时进行同步时不会发生冲突。

要避免性能命中,请不要将Guid放入群集索引中。 您始终可以使用不同的唯一字段作为集群ID,或者甚至可以使用增加1的整数标识字段作为“clusterId”并使用它。

另一个原因是当您聚合来自许多不同来源的数据时,如果UserId(主键)是Guid,则可以避免冲突。

像往常一样,微软更多地考虑“简单性”,而不是实际上有用和高效。 是GUID是系统范围内唯一的,是的,您可以测试它而无需从数据库中刷新新ID ….但是……

我甚至没有讨论DB索引,我相信很多人都会想到这些索引。 这是字符串的另一个缺点。 即使我在db中使用BIGINT作为用户ID,它仍然只有8个字节对varchar(128)。 我知道这些天磁盘空间很便宜,但为什么我要用不必要的东西弄乱我的数据库。 任何曾参与任何涉及数百万用户的项目的人都会对字符串作为用户ID。 微软关于“他们使用字符串的原因”的所有回复基本上都是回复。

当然他们会说:“你可以改变它来使用INT,BIGINT等……”当然,你必须改变无数的类,实现你自己的用户存储等等。对……这么简单的东西必须如此复杂。

/结束咆哮