SQL Server唯一GUID

时间:2011-05-10 20:46:30

标签: sql-server tsql

我理解在SQL Server中GUID是最独特的,并且碰撞的可能性很小,但同时有人必须赢得彩票,所以我觉得为这种可能性做准备是有道理的。

哪种更快/更好的练习

使用一种技术,我只需插入一行并检查错误(@@ ERROR<> 0)直接分配新的GUID,然后重复直到我没有收到错误[我认为理论上会只有在最糟糕的情况下才会... ...

或使用这样的方法

DECLARE @MyGUID uniqueidentifier
SELECT @MyGUID = NewID()
if exists(select * from tablename where UserID=@MyGUID)

然后循环,直到找到一个未使用的。

我喜欢第二种方法,因为我可以在后面的存储过程中使用GUID,所以我现在倾向于那个。

5 个答案:

答案 0 :(得分:7)

如果您的计算机中至少有一个网络适配器,那么您的GUID将是唯一的。如果你没有,那么理论上存在与另一台机器上产生的guid相撞的可能性,但永远不会发生在你身上。编写代码以防止重复的guid是完全浪费时间。

话虽如此,在关系数据库中强制执行任何的唯一性只能通过以下方式完成:在数据上创建unique constraint

ALTER TABLE tablename ADD CONSTRAINT uniqueUSerID UNIQUE UserID;

答案 1 :(得分:5)

计算机发生碰撞的可能性为much less likely than you winning the lottery

使用NEWID()并且不要担心极不可能发生的事件。

如果您将列声明为唯一,则无论如何都不会保留该列。

答案 2 :(得分:3)

碰撞的可能性非常低 - 远远低于赢得彩票的可能性 - 宇宙射线更有可能撞击机器中的RAM并导致程序以其他任意方式失败。对于这种情况,您的错误处理更可能(现在或最终)包含将导致失败的错误。有意尝试使用广泛的计算能力定位碰撞的研究人员到目前为止找不到甚至一个。我认为值得您花费精力或时间来处理此错误情况,至少在您处理可能发生的各种更可能的硬件和软件错误之前。我意识到这是违反直觉的,但请相信我。

答案 3 :(得分:3)

要真正回答问题而不是辩论问题/感知问题的优点。

第一个实现将是您要使用的实现,原因有两个:

  • 在为每个单独的记录执行插入之前运行检查,最终会导致更多资源专用于极不可能发生的事情。 (同样数据库也会确保对列的约束,所以如果碰撞数据就不会被提交)
  • 如果第一个出错,您可以多花点时间处理返回的错误。

您可以将两者合并,并将新的uniqueidentifier插入声明到表中(如果它继续使用它,否则重试一个新的,然后继续使用它。)

通常,您希望首先针对最可能的情况进行编程,然后再处理异常。

答案 4 :(得分:1)

通常,如果我正在处理客户端需要在离线时添加新记录的分布式数据库,我只使用GUID主键。如果这不是您的情况,那么最好使用自动增量int作为主键。