Asp.net SQL主键

Asp.net SQL主键,asp.net,sql-server,tsql,primary-key-design,Asp.net,Sql Server,Tsql,Primary Key Design,因此,我和一位同事正在争论哪种方式更适合生成作为guid的主键 我们将.NET 4.0与Entities 4一起使用,并使用存储过程进行选择/插入/更新 他希望在代码中创建GUID主键,并使用GUID类或/和某些创建的顺序GUID类将其作为插入的一部分传递回 我希望SQL Server在插入时使用newid()或newsequentialid()创建GUID 我反对他的观点是,如果您必须进行多个插入,那么您必须进行往返以获得每个插入的guid,这样您就可以为外键约束保持这种关系。另外,使用这种方

因此,我和一位同事正在争论哪种方式更适合生成作为guid的主键

我们将.NET 4.0与Entities 4一起使用,并使用存储过程进行选择/插入/更新

他希望在代码中创建GUID主键,并使用GUID类或/和某些创建的顺序GUID类将其作为插入的一部分传递回

我希望SQL Server在插入时使用newid()或newsequentialid()创建GUID

我反对他的观点是,如果您必须进行多个插入,那么您必须进行往返以获得每个插入的guid,这样您就可以为外键约束保持这种关系。另外,使用这种方法,每次插入都必须进行多次往返

他关于使用SQL进行操作的论点是,在插入发生之前,他没有访问密钥的权限,必须等待插入发生,才能将主键guid重新用于代码的其他部分。通过这种方式,您可以与存储的进程建立一个连接,它将处理所有插入


那么,哪种方法更适合单个插入?对于事务中的多个插入,哪种方法更好?

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

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

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

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

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

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

是的,我知道-在SQL Server 2005和更高版本中有
newsequentialid()
-但即使是这样也不是真正的完全顺序的,因此也会遇到与GUID相同的问题-只是不太明显而已。如果您坚持使用GUID,则至少在服务器上使用
newsequentialid()
方法

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

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

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

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


Marc

当我有这样的问题时,我会对自己说“SQL Server擅长设置,所以让它做它擅长的事情吧”,有时“1只是N的一个特例”

哪一种方法更适合于单个 插页

同步sql调用的两种方法的单次插入时间都相同。但是,“his”方法会给您带来更多的查找时间问题,因为他的顺序guid方法不如sql Server好(而且您可能会失去全局唯一性)。当您不可避免地需要执行多个插入时,它还将分割您的代码库

哪种方法更适合多个项目 在事务中插入

如果您认为基于集合的插入(插入/选择)与单行插入(插入)相比,基于集合的插入将在多次插入中获胜,因为返回客户的过程将是昂贵的部分


如果是我,我将创建一个SP,它接受要插入的对象的序列化集合,使用进行插入/选择,检查“Example B.Using OUTPUT with identity and computed columns”(示例B.Using OUTPUT with the identity and computed columns),让sql server创建GUID(如果您仍在使用它)然后返回到客户端或在SP中运行下一条语句,根据插入生成的输出表插入子行。

我不关心GUID主键的利弊。我们已经一次又一次地讨论过这个论点。我们也不关心数据库空间,因为我们有一个10tb的3PAR存储,到目前为止,我们的数据库几乎没有达到4 GB,数据库使用主键6年,超过1000万行。@Sean:你关心数据库性能吗?!??!阅读Kim Tripp的“磁盘空间很便宜”——她很好地展示了GUID在任何操作中的表现有多糟糕——但是,我也读过,尽管INT的表现比我们正在使用的顺序GUID好得多。运行som