【发布时间】:2019-09-26 01:13:00
【问题描述】:
我有一个存储唯一 nvarchar 数据集的 SQL 表,最大 60 个字符。
我现在需要每天将每个值输出到一个文件中。然后将该文件输入到第 3 方系统中。
但是,此第 3 方系统要求将值限制为 10 个字符。这些值不必是表中的值。它们只需要唯一且最多 10 个字符。它们还必须保持一致,因为表值每天都使用相同的唯一 ID。
我无法截断字符串,因为它可能会失去其唯一性。
看看我的选择,我可以:
- 使用 GetHashCode()
- 转换为十六进制
使用 GetHashCode,这看起来是一个简单直接的选项,每次运行时我都会得到相同的值。但是,Microsoft 文档建议不要将其用于我的目的...
因此,哈希码不应在创建它们的应用程序域之外使用,它们不应用作集合中的关键字段,也不应被持久化。
使用十六进制转换,修剪到10个字符时也可能失去唯一性。
我也看过这个例子,但我再次不确定它的唯一性有多可靠:A fast hash function for string in C#
static UInt64 CalculateHash(string read)
{
UInt64 hashedValue = 3074457345618258791ul;
for(int i=0; i<read.Length; i++)
{
hashedValue += read[i];
hashedValue *= 3074457345618258799ul;
}
return hashedValue;
}
我还有其他选择吗?
【问题讨论】:
-
考虑使用Guid
-
只生成一个序列,从“AAAAAAAAAA”开始,向上通过“AAAAAAAAAAB”等。理想情况下将其存储在数据库中,否则将真实字符串映射到字典中的序列。
-
鸽洞原理适用于此。 在一般情况下,您无法将 60 个字符的唯一键插入 10 个字符的字符串并保持它们都是唯一的。如果您可以对这个 60 个字符的字符串进行限制,例如“它们都是数字”,那么 也许 有人可以想出一个算法。
-
GetHashCode 也不保证冲突,这不是它的目的。
-
在我看来,最好的选择是在数据库中添加一个单独的 10 个字符的列,并在导出行时为该列分配新的唯一键。