为什么aspnet_regsql GUID生成主键?

时间:2011-04-26 01:27:43

标签: asp.net-membership asp.net-roles

我正在Visual Studio 2010中开发一个ASP.NET网站(使用Service Pack 1,非常感谢)。我想利用.NET的SQL Server 2008内置成员资格和角色提供程序。

现在,我已经开发了很长时间的微软技术,并且已经在业务中使用了一些最好的SQL Server DBA。在构建数据库表时,他们每个人都告诉我远离GUIDS作为主键

  1. 拥有非常高的记录数。
  2. 有大量插入和删除。
  3. 原因:因为主键是集群索引!

    这基本上意味着插入表的每条记录必须遵守索引的约束。因此,如果索引按ASC排序,则具有新生成的GUID的记录必须以适当的顺序物理地嵌入到相关数据表中。

    对于只有几千条记录的表来说,这样就好了。 SQL Server只需重新定位少数几个。但是,如果数据表具有数百万条记录,并且发现它必须在第216行插入新记录。可能需要花费大量时间(通过Web标准)才能完成。它必须将所有这些行物理移动,以插入新的行。

    所以我的问题就是这个。由于微软以及我们所熟知和喜爱的所有DBS都对GUID作为主键说不...为什么ASPNET_REGSQL工具使用GUID作为主键创建表?

    或者我错过了什么? 2008年SQL Profiler引擎是否有新功能,不再将GUIDS视为任务?

2 个答案:

答案 0 :(得分:3)

Guids确实有一些优势;例如,如果要在应用程序代码中生成guid,则可以在Web场中生成它们,而无需担心最终使用相同的ID。另一个好处是可以锁定数据库中的页面而不会引起任何问题,因为在同一数据页中不太可能存在两个随机选择的行。

就你所说的几百万行数据而言 - 只要你总是要求SQL服务器返回一行数据,Guids就可以了。最大的问题是当你要求大量的数据子集或批量插入大量行时;然后,您可能会进行大量随机I / O以获取符合条件的所有行,或将所有行插入到guids最终指向的随机位置。此外,SQL不必“将所有这些行物理移动以插入新行”;数据存储在页面上,SQL通常只需要更改数据文件中一个页面上的数据以插入行,可能还会更新其他几个页面,但这不像是在一个海量文本文件中插入一行。

所有这些都说 - 是的,我通常也更喜欢一个整数作为主键,但只是想指出肯定存在guids有意义的情况。

答案 1 :(得分:1)

使用GUID作为主键没有任何问题。如果使用不当,肯定会有一些不利因素,但考虑到你在商店或其他销售点拥有各种数据库的情况,每天晚上,你需要从每个地点获取所有数据并将其合并为一个公司的主数据库。 GUID在这里是一个很好的选择,因为您不需要担心身份冲突。

  

他们每个人都告诉我在构建数据库时远离GUIDS作为主键...因为主键是聚集索引!

主键不必使用聚簇索引,这只是创建主键时使用的默认索引类型。

实际上,如果查看SqlMembershipProvider使用的数据库架构,您会发现主键列上有 nonclustered 索引。

以下是InstallCommon.sql%WINDIR%\Microsoft.NET\Framework\v4.0.30319脚本的SQL脚本:

  CREATE TABLE [dbo].aspnet_Users (
    ApplicationId    uniqueidentifier    NOT NULL FOREIGN KEY REFERENCES [dbo].aspnet_Applications(ApplicationId),
    UserId           uniqueidentifier    NOT NULL PRIMARY KEY NONCLUSTERED DEFAULT NEWID(),
    UserName         nvarchar(256)       NOT NULL,
    LoweredUserName  nvarchar(256)       NOT NULL,
    MobileAlias      nvarchar(16)        DEFAULT NULL,
    IsAnonymous      bit                 NOT NULL DEFAULT 0,
    LastActivityDate DATETIME            NOT NULL)

   CREATE UNIQUE CLUSTERED INDEX aspnet_Users_Index ON [dbo].aspnet_Users(ApplicationId, LoweredUserName)
   CREATE NONCLUSTERED INDEX aspnet_Users_Index2 ON [dbo].aspnet_Users(ApplicationId, LastActivityDate)

请注意,主键列(UserId)是使用语句PRIMARY KEY NONCLUSTERED创建的,并且表的CLUSTERED索引是作为ApplicationId上的复合索引创建的,{ {1}}。