GUID创建是否比.net中的System.Guid.NewGuid()更好

时间:2012-06-29 14:07:03

标签: c# asp.net sql visual-studio-2010 sql-server-2008

在我的应用程序代码中,我使用System.Guid.NewGuid()生成GUID并将其保存到SQL Server DB。

关于GUID生成我几乎没有问题:

  1. 当我运行程序时,我在性能方面没有发现任何问题,但我仍然想知道我们是否还有其他更好的方法来生成GUID。
  2. System.Guid.NewGuid()这是在.NET中创建GUID的唯一方法 码?

4 个答案:

答案 0 :(得分:5)

根据SQL Server排序顺序,Guid.NewGuid生成的GUID不是顺序的。这意味着您将随机插入索引,这对性能造成了灾难。如果写入量足够小,则可能无关紧要。

您可以使用SQL Server NEWSEQUENTIALGUID()函数创建顺序函数,或者只使用int。

答案 1 :(得分:2)

生成guid的另一种方法(我假设你的PK)是将表中的列设置为:

create table MyTable(
    MyTableID uniqueidentifier not null default (newid()),
...

这样的实现意味着您可以选择是否在.Net中设置它们或让SQL执行它。

我不会说要么“更好”,要么“更快”。

答案 2 :(得分:2)

回答这个问题:

  

是否有更好的GUID创建选项   .net

中的System.Guid.NewGuid()

我冒昧地说System.Guid.NewGuid()是首选。

但是对于后续问题:

  

...将其保存到SQL Server DB。

答案不太清楚。这已经在网上讨论了很长时间。只是谷歌“ guid as primary key ”,你将有几个小时的阅读时间。

通常在Sql server中使用Guid时,原因是在表中使用主键。这有很多好处:

  • 无需访问数据库即可轻松生成新值
  • 您可以合理地确定您本地生成的Guid不会导致主键冲突

但也存在重大缺陷:

  • 如果主键也是聚簇索引,则插入大量新行将导致大量IO(磁盘操作)和索引更新。
  • 与代理键的其他流行替代品int相比,Guid相当大。由于表中的所有其他索引都包含聚簇索引键,因此如果您有Guid与int,它们的增长速度会快得多。
  • 这也将导致更多IO,因为这些索引需要更多内存

为了缓解IO问题,Sql Server 2005引入了一个新的NEWSEQUENTIALGUID()函数,可用于在插入新行时生成顺序Guids。但是如果你想使用它,那么你将不得不与数据库联系生成一个,所以你失去了在离线时生成一个的可能性。在这种情况下,你仍然可以生成一个普通的Guid并使用它。

网上还有很多关于如何滚动自己的连续Guids的文章。一个样本:

http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database

我没有测试任何一个,所以我不能保证它们有多好。我选择了特定的样本,因为它包含一些可能有趣的信息。具体做法是:

  

它变得更加复杂,因为微软的一个怪癖   SQL Server是它根据最少的顺序命令GUID值   有效的六个字节(即Data4块的最后六个字节)。   因此,如果我们想要创建一个用于SQL Server的顺序GUID,我们   必须将顺序部分放在最后。其他大多数数据库   系统会在一开始就想要它。

编辑:由于问题似乎是使用批量复制插入大量数据,因此可能需要使用顺序Guid。如果在插入之前没有必要知道Guid值,那么 Jon Egerton 的答案将是解决问题的一种好方法。如果您需要事先了解Guid值,则必须生成插入或使用变通方法时要使用的顺序Guids。

一种可能的解决方法是将表更改为使用种子INT作为主键(和聚簇索引),并将Guid值作为具有唯一索引的单独列。插入时,Guid将由您提供,而seded int将是聚集索引。然后将按顺序插入行,并且您生成的Guid仍可用作以后获取记录的备用键。我不知道这是否是一个可行的解决方案,但它至少是一种可能的解决方法。

答案 3 :(得分:0)

NewGuid将是一般推荐的方式 - 除非你需要顺序值,在这种情况下你可以P / Invoke到rpcrt函数UuidCreateSequential

Private Declare Function UuidCreateSequential Lib "rpcrt4.dll" (ByRef id As Guid) As Integer

(抱歉,从VB中删除,确定您可以转换为C#或其他.NET语言as required)。