为 SQL Server 中的字段生成唯一哈希



我正在编写一个会员提供程序,用于我们现有的会员基础。 我将 EF4.1 用于我的所有数据库访问,我遇到的问题之一是最初设置数据库时,关系是以编程方式完成的,而不是在数据库中完成的。 一个是需要在不是所有用户都需要的列上建立关系,但为了使关系确实需要是唯一的(根据我的理解)。

我相信会起作用的解决方案是在用户 id 字段上进行 MD5 哈希(这是唯一的......这将/应该保证该领域的唯一值)。 我在sql服务器上遇到问题的部分是查询,该查询可以在不替换存储在employeeNum字段中的现有值(有问题的字段)的情况下执行此操作。

所以简而言之,

我的问题是。 在尚未存在值的所有行的 employeeNum 字段中获取唯一值(可能基于 userid 字段的 md5 哈希)的最佳方法是什么。 此外,在次要/主要程度上...这听起来像是一个好计划吗?

如果您的问题只是如何为 userid 生成哈希值,您可以使用计算列以这种方式执行此操作(或作为插入过程的一部分生成此值)。我不清楚你是否知道HASHBYTES函数,或者当你说"最好"时,你正在看什么其他标准。

DECLARE @foo TABLE
(
  userid INT, 
  hash1 AS HASHBYTES('MD5',  CONVERT(VARCHAR(12), userid)),
  hash2 AS HASHBYTES('SHA1', CONVERT(VARCHAR(12), userid))
);
INSERT @foo(userid) SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 500;
SELECT userid, hash1, hash2 FROM @foo;

结果:

userid  hash1                               hash2
------  ----------------------------------  ------------------------------------------
1       0xC4CA4238A0B923820DCC509A6F75849B  0x356A192B7913B04C54574D18C28D46E6395428AB
2       0xC81E728D9D4C2F636F067F89CC14862C  0xDA4B9237BACCCDF19C0760CAB7AEC4A8359010B0
500     0xCEE631121C2EC9232F3A2F028AD5C89B  0xF83A383C0FA81F295D057F8F5ED0BA4610947817

在SQL Server 2012中,我强烈建议至少使用SHA2_256而不是上述任何一种。(您忘了提及您正在使用的版本 - 总是有用的信息。

综上所述,我仍然想提请注意我在评论中提出的观点:这里的"最佳"解决方案是修复模型。如果 employeeNum 是可选的,则不应使 EF 认为它是必需的或唯一的,如果它实际上不是某种标识符,则不应在关系中使用它。如果您首先为关系使用正确的属性,为什么用户会关心employeeNumuserid之间的冲突?

根据 OP 的要求进行编辑

那么说UPDATE table SET EmployeeNum = 1000000 + UserID WHERE EmployeeNum IS NULL有什么错呢?如果EmployeeNum将保持在1000000以下,那么您已经保证没有冲突,并且您完全避免了哈希。

如果employeeNum可能包含字符串,则可以生成类似的填充,但同样是 EF 促进了这些可怕的列名吗?为什么带有Num后缀的列包含数字以外的任何内容?

您也可以使用唯一标识符将默认值设置为 (newid())

创建一个新列 EmployeeNum 作为唯一标识符,然后:

UPDATE Employees SET EmployeeNum = newid()

然后设置为主键。

UPDATE EMPLOYEE
    SET EMPLOYEENUM = HASHBYTES('SHA1', CAST(USERID AS VARCHAR(20)))
WHERE EMPLOYEENUM IS NULL

最新更新