Sql server 2008 EF 4.0 Guid或Int作为主键

Sql server 2008 EF 4.0 Guid或Int作为主键,sql-server-2008,entity-framework-4,Sql Server 2008,Entity Framework 4,我正在使用EF4.0实现自定义ASPNetMembership 我为什么要在用户表中使用Guid作为主键 据我所知,在SQL Server上,Int作为PK的性能比字符串更高 Int更容易迭代。 此外,为了安全起见,如果我需要在某个地方传递任何int-id,例如在url中,我可能会以某种方式对其进行加密,并像字符串一样毫无问题地传递它 但是,如果我想使用EF4.0在SQL Server端使用自动生成的Guid,我需要这样做 我看不出为什么我应该使用Guid作为PK,如果系统将拥有数百万用户,这可

我正在使用EF4.0实现自定义ASPNetMembership

我为什么要在用户表中使用Guid作为主键

据我所知,在SQL Server上,Int作为PK的性能比字符串更高

Int更容易迭代。 此外,为了安全起见,如果我需要在某个地方传递任何int-id,例如在url中,我可能会以某种方式对其进行加密,并像字符串一样毫无问题地传递它

但是,如果我想使用EF4.0在SQL Server端使用自动生成的Guid,我需要这样做

我看不出为什么我应该使用Guid作为PK,如果系统将拥有数百万用户,这可能是唯一的一种情况,但从理论上讲,Guid有时可以复制,不是吗

总之,Int32的大小是2147.483.647,这对于非常大的系统来说几乎是一样的,但是如果这个数字仍然不够,我可以使用Int64,在这种情况下,我可能有9223.372.036.854.775.807行。差不多吧

另一方面,M$在其ASPNetMembership实现中使用GUID作为PK。[aspnetdb].[aspnet_Users]->PK UserId类型uniqueidentifier, 应该有一些原因/解释为什么他们这么做


可能有人对此有任何想法/经验?

我100%同意你的看法-使用
INT标识
要好得多

guid似乎是主键的自然选择——如果您真的必须这样做,您可能会争论将其用于表的主键。我强烈建议不要做的是使用GUID列作为集群键,SQL Server默认情况下会这样做,除非您明确告诉它不要这样做

您确实需要将两个问题分开:

1) 主键是一个逻辑结构-唯一且可靠地标识表中每一行的候选键之一。这可以是任何东西,真的-一个INT,一个GUID,一个字符串-选择对您的场景最有意义的内容

2) 聚集键(表中定义“聚集索引”的一列或多列)-这是一个与物理存储相关的东西,在这里,一个小的、稳定的、不断增加的数据类型是您最好的选择-INT或BIGINT作为默认选项

默认情况下,SQL Server表上的主键也用作集群键-但不需要这样!我个人看到,将以前基于GUID的主键/聚集键拆分为两个单独的键时,性能有了巨大的提高—GUID上的主键(逻辑键)和单独INT-IDENTITY(1,1)列上的聚集键(排序键)

正如《索引女王》和其他人多次指出的那样,作为集群键的GUID并不是最优的,因为由于其随机性,它将导致大量页面和索引碎片,并导致总体性能不佳

是的,我知道-在SQL Server 2005和更高版本中有
newsequentialid()
-但即使是这样也不是真正的完全顺序的,因此也会遇到与GUID相同的问题-只是不太明显而已

然后还有另一个需要考虑的问题:表上的集群键也将添加到表中每个非集群索引的每个条目中——因此您确实希望确保它尽可能小。通常,对于绝大多数表来说,一个20多亿行的INT就足够了——与作为集群键的GUID相比,您可以在磁盘和服务器内存中节省数百兆的存储空间

快速计算-使用INT vs.GUID作为主键和群集键:

  • 包含1'000'000行的基表(3.8MB与15.26MB)
  • 6个非聚集索引(22.89MB对91.55MB)
总计:25MB对106MB-这只是在一张桌子上

更多值得思考的东西——金伯利·特里普的优秀作品——读一读,再读一读,消化它!这是SQL Server索引的福音,真的


使用INT PK。请参阅Kimberly L.Tripp的文章:

在实体框架引入任何批处理概念之前,没有理由不使用INT-IDENTITY。Guid仅在您希望在客户端上设置新记录的Id时才有用。

下面是我关于Guid PK与Int PK性能的相关问题