EF 4.0 Guid或Int作为主键

时间:2011-01-04 13:01:11

标签: sql-server-2008 entity-framework-4

我正在使用EF 4.0实现自定义ASPNetMembership

我有什么理由可以将Guid用作用户表中的主键吗?

据我所知,Int作为SQL Server上的PK比字符串表现得更好。

Int更易于迭代。 此外,出于安全目的,如果我需要在某个地方传递任何int id,例如在url中,我可能以某种方式加密它并将其传递为没有probs的字符串。

但是,如果我想使用EF 4.0在SQL Server端使用自动生成的Guid,我需要做这个技巧http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/

我看不出为什么我应该使用Guid作为PK的任何情况,如果系统将拥有数百万的数百万用户,可能只有一个,但理论上,Guid可能在某些时候重复并非如此?

无论如何Int32的大小是2,147.483.647它甚至非常非常大的系统,但如果这个数字仍然不够,我可以使用Int64,在那种情况下我可能有9,223.372.036.854.775.807行。差不多吧?

另一方面,M $在他们的ASPNetMembership实现中使用Guids作为PK。 [aspnetdb]。[aspnet_Users] - > PK UserId类型uniqueidentifier, 应该是一些原因/解释为什么这样做了?!

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

3 个答案:

答案 0 :(得分:21)

我会100%同意你 - 使用INT IDENTITY要好得多!

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

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

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

2)群集密钥(定义"聚集索引"在表上的一列或多列) - 这是物理存储 - 相关的东西,在这里,一个小的,稳定的,不断增加的数据类型是你最好的选择 - INT或BIGINT作为你的默认选项。

默认情况下,SQL Server表上的主键也用作群集键 - 但这不是必须的! I' - 对GUID主(逻辑)键,在一个单独的INT IDENTITY聚类(排序)键(分手时,前面的基于GUID的主/聚集键分成两个单独的密钥已经亲眼见过巨大的性能提升1,1)专栏。

作为Kimberly Tripp - 索引女王 - 以及其他人已多次说过 - GUID作为聚类键并不是最佳的,因为由于其随机性,它将导致大量页面和索引碎片化和一般性能不佳。

是的,我知道 - 在SQL Server 2005及更高版本中有newsequentialid() - 但即使这样也不是真正完全顺序的,因此也会遇到与GUID相同的问题 - 只需少一点显着如此。

然后还有另外一个需要考虑的问题:表格上的聚类键也会添加到表格中每个非聚集索引的每个条目上 - 因此你真的想确保它和#39; s尽可能小。通常,对于绝大多数表来说,具有2亿行的INT应该足够 - 并且与作为群集密钥的GUID相比,您可以在磁盘和服务器内存中节省数百兆的存储空间。

快速计算 - 使用INT与GUID作为主要和群集密钥:

  • 基本表,1' 000' 000行(3.8 MB对15.26 MB)
  • 6个非聚簇索引(22.89 MB vs. 91.55 MB)

TOTAL:25 MB vs. 106 MB - 这只是在一张桌子上!

更多值得思考的东西 - 金佰利特里普的优秀作品 - 阅读,再读一遍,消化它!它确实是SQL Server索引福音书。

答案 1 :(得分:3)

使用INT PK。见Kimberly L. Tripp的文章:GUIDs as PRIMARY KEYs and/or the clustering key

答案 2 :(得分:2)

在Entity Framework引入任何批处理概念之前,没有理由不使用INT IDENTITY。只有当您想在客户端上设置新记录的ID时,Guid才有用。