6

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

现在,我已经开发 Microsoft 技术很长时间了,并且与业内一些最优秀的 SQL Server DBA 擦肩而过。他们每个人都告诉我在构建数据库表时远离GUIDS 作为主键:

  1. 拥有非常高的记录数。
  2. 有大量的插入和删除。

原因:因为主键是聚集索引!

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

这对于只有几千条记录左右的表来说就很好了。SQL Server 只需要重新定位一小部分。但是,如果数据表有几百万条记录,并且发现它必须在第 216 行插入新记录。这可能需要大量时间(按 Web 标准)才能完成。它必须物理地将所有这些行向下移动,以插入新行。

所以我的问题就是这个。既然 Microsoft 以及我们所知道和喜爱的所有 DBS 都拒绝将 GUID 作为主键......为什么 ASPNET_REGSQL 工具使用 GUID 作为主键来创建表?

还是我错过了什么?2008 年的 SQL Profiler 引擎是否有一项新功能不再将 GUIDS 视为一项任务?

4

2 回答 2

3

向导确实有一些优势。例如,如果您在应用程序代码中生成 guid,则可以在网络场中生成它们,而不必担心最终得到相同的 ID。另一个好处是可以锁定数据库中的页面,而不会导致任何问题,因为两个随机选择的行不太可能存在于同一数据页面中。

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

所有这一切 - 是的,我通常也更喜欢整数作为主键,但只是想指出,在某些情况下 guid 肯定是有意义的。

于 2011-04-26T01:51:24.903 回答
1

使用 GUID 作为主键没有任何问题。如果使用不当,它们可能会产生一些损害,当然,但考虑一个场景,您在商店或其他销售点拥有各种数据库,并且每天晚上,您需要从每个位置获取所有数据并将其组合成一个企业主数据库。GUID 在这里是一个很好的选择,因为您无需担心身份冲突。

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

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

事实上,如果您查看使用的数据库模式,SqlMembershipProvider您会发现主键列上有一个非聚集索引。

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

  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索引是作为 和 上的复合索引创建ApplicationIdLoweredUserName

于 2011-04-26T02:24:22.727 回答