在我的应用程序代码中,我使用生成 GUIDSystem.Guid.NewGuid()
并将其保存到 SQL Server DB。
关于 GUID 生成,我有几个问题:
- 当我运行程序时,在性能方面我没有发现任何问题,但我仍然想知道我们是否有其他更好的方法来生成 GUID。
System.Guid.NewGuid()
这是在 .NET 代码中创建 GUID 的唯一方法吗?
在我的应用程序代码中,我使用生成 GUIDSystem.Guid.NewGuid()
并将其保存到 SQL Server DB。
关于 GUID 生成,我有几个问题:
System.Guid.NewGuid()
这是在 .NET 代码中创建 GUID 的唯一方法吗?Guid.NewGuid
根据 SQL Server 的排序顺序,生成的 GUID不是连续的。这意味着您将随机插入到索引中,这对性能来说是一场灾难。如果写入量足够小,这可能并不重要。
您可以使用 SQL ServerNEWSEQUENTIALGUID()
函数来创建顺序函数,或者只使用 int。
生成 guid 的另一种方法(我认为是您的 PK)是像这样设置表中的列:
create table MyTable(
MyTableID uniqueidentifier not null default (newid()),
...
像这样实现意味着您可以选择是在.Net 中设置它们还是让SQL 来做。
不过,我不会说两者都会“更好”或“更快”。
要回答这个问题:
有没有比 .net 中的 System.Guid.NewGuid() 创建 GUID 更好的选择
我敢说 System.Guid.NewGuid() 是首选。
但是对于后续问题:
...将其保存到 SQL 服务器数据库。
答案不太清楚。这在网上已经讨论了很长时间。只需谷歌“ guid as primary key ”,您将有数小时的阅读时间。
通常,当您在 Sql 服务器中使用 Guid 时,这是因为在表中用作主键。这有很多不错的优点:
但也有明显的缺点:
为了缓解 IO 问题,Sql Server 2005 引入了一个新的 NEWSEQUENTIALGUID() 函数,可用于在插入新行时生成顺序 Guid。但是,如果您打算使用它,那么您将必须与数据库联系才能生成一个,因此您在离线时失去了生成一个的可能性。在这种情况下,您仍然可以生成一个普通的 Guid 并使用它。
网上也有很多关于如何滚动自己的顺序指南的文章。一个样本:
http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database
我没有测试过它们中的任何一个,所以我不能保证它们有多好。我选择了那个特定的样本,因为它包含一些可能很有趣的信息。具体来说:
它变得更加复杂,因为 Microsoft SQL Server 的一个怪癖是它根据最低有效六个字节(即 Data4 块的最后六个字节)对 GUID 值进行排序。因此,如果我们想创建一个用于 SQL Server 的顺序 GUID,我们必须将顺序部分放在末尾。大多数其他数据库系统一开始就需要它。
编辑:由于问题似乎是关于使用批量复制插入大量数据,因此可能需要一个顺序 Guid。如果在插入之前不需要知道 Guid 值,那么Jon Egerton的答案将是解决问题的一种好方法。如果您需要事先知道 Guid 值,则必须生成顺序 Guid 以在插入时使用或使用解决方法。
一种可能的解决方法是更改表以使用种子 INT 作为主键(和聚集索引),并将 Guid 值作为具有唯一索引的单独列。插入时,Guid 将由您提供,而种子 int 将是聚集索引。然后将按顺序插入行,您生成的 Guid 仍可用作稍后获取记录的备用键。我不知道这是否对您来说是一个可行的解决方案,但它至少是一种可能的解决方法。
NewGuid
将是通常推荐的方式 - 除非您需要顺序值,在这种情况下,您可以 P/Invoke 到 rpcrt 函数UuidCreateSequential:
Private Declare Function UuidCreateSequential Lib "rpcrt4.dll" (ByRef id As Guid) As Integer
(对不起,从 VB 中删除,请确保您可以根据需要转换为 C# 或其他 .NET 语言)。