【问题标题】:Is INT the correct datatype for ABS(CHECKSUM(NEWID()))?INT 是 ABS(CHECKSUM(NEWID())) 的正确数据类型吗?
【发布时间】:2013-11-06 20:31:49
【问题描述】:

我正在创建唯一的客户 ID,这是供外部使用的替代 ID。

在为我的唯一 ID 添加数据类型为 INT 的新列“cust_uid”的过程中,

当我在这个新列中插入时:

Insert Into Customers(cust_uid)
Select ABS(CHECKSUM(NEWID()))

我收到一个错误:

无法创建可接受的游标。链接服务器“SHQ2IIS1”的 OLE DB 提供程序“SQLNCLI”返回消息“多步 OLE DB 操作产生错误。检查每个 OLE DB 状态值(如果可用)。没有完成任何工作。

我检查了两个表上的所有数据类型,唯一改变的是两个表中的新列。

更新是在一张 @$$ 大桌子上完成的...由于我的工资等级以上的原因,我们希望有新的 uid,与我们目前拥有的不同,“所以用户不知道我们实际上有多少个账户。”

  • INT 是 ABS(CHECKSUM(NEWID())) 的正确数据类型吗?

【问题讨论】:

  • 根据文档校验和返回 int。但是为什么要使用它来创建唯一的客户 ID?
  • 我们已经为客户准备了 Uid ......这仅供外部使用。仅供参考,插入也在运行 MS-SQL Server 2000 的旧服务器上完成,运行版本 8.00.2039
  • 再说一遍,为什么要使用它来创建唯一 ID?当然,发生碰撞的可能性很低,但您的 ID 也很长。为什么不只是 1 - X(一个标识列)。
  • 这行不通。散列向导会产生冲突。他们的号码取决于客户的号码,但你不能称它为安全的任何值。这就是为什么你有 128 位 GUID,然后你有 32 位哈希值。
  • 假设您不关心重复的可能性,错误消息似乎与数据类型无关。出于好奇,您能否尝试使用ABS(CHECKSUM(NEWID())) 的结果填充INT 变量并将其用于插入以查看会发生什么?

标签: sql sql-server tsql


【解决方案1】:

暂时忘记您的问题,即必须尝试插入链接服务器(尽管从您的代码中看不出Customers 必须是同义词,或者您将语句简化了)。

问问自己:为什么要使用随机数来实现唯一性?随机和独特可能看起来像是相似的概念,但实际上并非如此。

我还发现缺乏错误处理(同样,这可能只是您简化了代码以“帮助”我们)。最终你会得到重复。您可能想阅读this tipthis blog post。本质上,当您插入越来越多的“唯一”值时,发生碰撞的可能性就会增加。因此,与其用你的解决方案来解决问题,我认为你应该退后一步,重新考虑问题。

为什么要使用随机数而不是更简单的概念——至少在默认情况下——以更可预测的方式帮助确保唯一性,例如 IDENTITYSEQUENCE?是防止人们猜测下一个值,还是能够确定您在一段时间内生成了多少值?如果是这样,则使用一堆随机值预先填充一个表,并在需要时从堆栈中拉出一个,as I described here。如果这不是关键问题,那就不要再折腾了,只需使用现有的方法来生成唯一而非随机的数字。

【讨论】:

  • 我继承了一个代码库,其中包含var tempGuid = random.Next(10000, 1000000) 之类的东西。我的周末就这样过去了。所以是的,请坚持使用唯一编号作为唯一标识符。
  • 谢谢@AaronBertrand...我正在做的事情从根本上来说是错误的,它只是没有意义。问题:如果我使用 IDENTITY 或 SEQUENCE,那么 ABS(CHECKSUM(cust_id)) 应该可以工作...cust_id 已经是 IDENTITY 列了。
  • @Chad 我无法理解您使用 ABS(CHECKSUM()) 的目的。
  • 高层对我有问题,从(1)开始,这确实用于 ASP Web 开发/查询字符串解析 .../index.aspx?clientID=123456789 ....I我是KISS 的忠实拥护者
  • @ChadSellers 从 1 开始,但是当您将其呈现给用户时,将值与常数进行异或,反之亦然。但不要将晦涩的数字与安全混淆。
【解决方案2】:

更新是在一张 @$$ 大桌子上完成的...由于我的工资等级以上的原因,我们希望有新的 uid,与我们目前拥有的不同,“所以用户不知道我们实际拥有多少个帐户。”

选择一个常数并将其与现有标识符进行异或,以获得一个有点混淆的数字。再次 XOR 以获取原始标识符。

【讨论】:

    【解决方案3】:

    再次生成唯一 ID 的错误选择

    但话虽如此,这不会引发错误,所以我认为还有其他事情发生

    declare @id int 
    set @id = ABS(CHECKSUM(NEWID())) 
    print @id 
    

    您不希望用户知道有多少个帐户和 custID 是一个身份的更新应该已经在原始问题陈述中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 2015-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多