【发布时间】:2020-06-18 23:25:42
【问题描述】:
我正在玩弄在 noSQL 数据库中使用 Guid 作为 PrimaryKey 的想法,这是三个不同属性的组合(这可能是个坏主意)。这三个属性是;两个整数和一个 DateTime - 它们在组合时是唯一的。我使用 Guid 的原因是因为相同结构的预先存在的数据使用 Guid 而不是这些属性来查找数据。
如果我将它们转换为字符串并连接它们。然后我转换为 byte[] 并创建一个 Guid。发生碰撞的可能性有多大?我认为散列将是这里的问题?如果我使用弱的 16 字节散列算法,例如 MD5,如果属性不同,两个 guid 匹配(冲突)的机会是多少?例如整数和日期时间?如果我使用像 SHA256 这样的散列算法并且只使用前 16 个字节而不是 MD5,会发生什么情况?碰撞的几率还是一样吗?
否则,如果需要,我还有其他选项,例如二次查找,但这会使写入、读取和成本加倍。
例子:
public static Guid GenerateId(int locationId, int orderNumber, DateTime orderDate)
{
var combined = $"{locationId}{orderNumber}{orderDate.ToString("d", CultureInfo.InvariantCulture)}";
using (MD5 md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(combined));
return new Guid(hash);
}
}
【问题讨论】:
-
为什么要散列?如果您确定这三个参数的组合始终是唯一的,则使用该数据创建一个 GUID,DateTime 的长度为 8 个字节,整数为 4,因此您有 16 个字节,即 GUID 的确切长度...