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



正如标题所说,我想知道为什么ASP。. NET Identity 2.0使用带有GUID的字符串作为用户表的主集群键。这与整数id相比有什么优势吗?我只看到一个问题,GUID不是聚集索引的最佳选择。

我错过了什么,还是一个整数仍然是更好的选择?

关于guid的使用,有一种观点提倡使用没有"含义"的id,以便将标识符与其周围的数据完全分离;这个id不应该在数据存储之外可见。如果我们看一下代理键的一些特征,我们有以下

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

所以guid符合要求,因为它确实是由系统生成的,与域没有关系。我认为,在这种特殊的思维方式中,向导的使用主要是一个趋势问题;但是,由于他们引入了一种新的"可扩展主键"机制,因此键可以更改,因此您可以在PK中使用整数。


关于性能,我会指出你这个线程,其中接受的答案说:

guid似乎是主键的自然选择你真的必须,你可能会争论将它用于PRIMARY表的KEY。我强烈建议不要使用GUID列作为集群键,SQL Server默认是这样做的。除非你特别告诉它不要。

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

  • 主键是一个逻辑结构——唯一且可靠地标识表中每一行的候选键之一。这可以是任何东西,真的-一个INT,一个GUID,一个字符串-选择什么
  • 集群键(在表上定义"集群索引"的列或列)——这与物理存储有关在这里,一个小的、稳定的、不断增长的数据类型是你的最佳选择- INT或BIGINT作为默认选项。

完全证实了你的印象。

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

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

像往常一样,微软考虑的更多的是"简单性",而不是实用性和性能。是的GUID是系统范围内唯一的,是的,你可以测试它,而不需要从数据库中刷新新的ID ....但是…

我甚至不讨论DB索引,我相信很多人都想到了。这是弦的另一个缺点。即使我在数据库中使用BIGINT作为用户id,它仍然只有8个字节,而varchar(128)。我知道现在磁盘空间很便宜,但是为什么我要用不必要的东西把数据库弄得乱七八糟呢?任何参与过涉及数百万用户的项目的人都不会喜欢字符串作为用户标识。微软关于"他们为什么使用字符串"的所有回答基本上都是不屑一顾的回答。

当然他们会说:"你可以把它改成使用int, bigint等等...."当然,你必须改变无数的类,实现你自己的用户商店等等。对吧……这么简单的事情就得这么复杂。

/end rant

我假设您所说的"to an id"是指一个顺序整数id,因为UUID毕竟是一个id。

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

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

对于使用自然键(如用户名)有一个争论,其优点和缺点通常都经过了充分的研究。IIRC,他们确实第一次这样做了。

总之,UUID似乎是一个显而易见的选择。

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

当人们对GUID"咆哮"时要考虑的是,他们可能不会考虑"偶尔连接"的应用程序,在这种应用程序中,你不能在重新连接之前访问数据库以获得你的"int"标识字段值,但需要在离线连接在一起的各种表中创建多个记录。有一个Guid允许应用程序创建一个"user",因此"userId"作为主键,当你在线同步时不会发生冲突。

为了避免性能影响,不要将Guid放在集群索引中。您总是可以使用一个不同的唯一字段作为集群id,或者甚至可以使用一个增加1的整数标识字段作为"clusterId",并使用它。

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

最新更新