Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我们应该使用基于命名的GUID进行密钥标识吗?_C#_.net_Guid_Uuid - Fatal编程技术网

C# 我们应该使用基于命名的GUID进行密钥标识吗?

C# 我们应该使用基于命名的GUID进行密钥标识吗?,c#,.net,guid,uuid,C#,.net,Guid,Uuid,现在,我们正在寻找为一些字符串值(文件URL)生成一些唯一的、确定性的ID。基于此链接,看起来我们可以基于MD5哈希或Sha1哈希创建GUID(类型3或类型5,请参阅)。我在互联网上也做了一些搜索,我认为这基本上是一样的,基本上是基于哈希生成一个确定的GUID 当我第一次看到它时,它看起来很棒,但是我仍然不习惯使用它作为识别某些东西的关键。我认为通常使用哈希来检查: 两个字符串是否匹配而不显示原始字符串的内容 是否更改了某些字符串/文件内容 在这里,即使散列值有一些冲突,也不是很好,但它是可以的

现在,我们正在寻找为一些字符串值(文件URL)生成一些唯一的、确定性的ID。基于此链接,看起来我们可以基于MD5哈希或Sha1哈希创建GUID(类型3或类型5,请参阅)。我在互联网上也做了一些搜索,我认为这基本上是一样的,基本上是基于哈希生成一个确定的GUID

当我第一次看到它时,它看起来很棒,但是我仍然不习惯使用它作为识别某些东西的关键。我认为通常使用哈希来检查:

  • 两个字符串是否匹配而不显示原始字符串的内容
  • 是否更改了某些字符串/文件内容
  • 在这里,即使散列值有一些冲突,也不是很好,但它是可以的,一旦数据再次更改,它会自动更正,并且不会覆盖其他不相关的数据。然而,如果我们使用散列作为主键来标识一些数据,冲突将意味着我们将覆盖一些不相关的数据,一旦发生覆盖,就无法进行自我更正

    因此,在我看来,我们应该在这里使用数据库来真正生成确定性GUID,而不是依赖哈希:

  • 在数据库中有一个包含两列的表:str_val、guid_val。str_val是主键
  • 如果我们需要为string1生成guid,我们将尝试在表中查找记录
  • 如果我们能找到guid,我们就完成了
  • 如果找不到guid,则执行插入逻辑。若insert失败,很可能是因为其他线程只插入了一个线程,但这可能是正常的,因为insert竞争应该很少发生 就在我要发布我的问题之前,我看到了这个stackoverflow帖子:,它使用散列作为文件标识,接受的答案认为可以使用散列作为密钥。再一次,我觉得我仍然需要更多的说服力


    如果有人能提出更多建议,我将不胜感激

    在这种上下文中谈论guid或uuid是令人困惑的

    关键是

  • 输入函数(散列,可以是“确定性GUID”或其他形式)或
  • 独立于输入,如随机GUID或自动递增ID
  • 范围(所有可能的输出)小于域(所有可能的输入)的所有哈希值都将由于冲突而发生冲突。然而,我们的想法是使用一个适当的散列,这将在相关问题中讨论

    还有其他目标,例如“用相同的哈希值查找两个不同的消息是不可行的。”(也就是说,即使有人在尝试,生成冲突仍然是不切实际的-MD5在此失败,并被认为已损坏;SHA-1已被禁用。)

    如果密钥独立于数据(例如,不是散列),那么我们最好使用一个自动增量ID——它是确定性的,尽管与数据无关,并且由数据库保证唯一性——并称之为一天


    因此,使用散列,密钥是标识数据的自然密钥的一种形式。这使得仅使用哈希查询数据库成为可能。而且,如果我们相信客户机从手头的数据生成了散列,那么通常可以假设客户机拥有导致散列的数据

    使用“独立确定性值”时,键是标识元组的代理键。在这种情况下,如果“ID”未知,我们需要查询数据以找到适当的数据。这当然要求客户机在此类查询中使用原始数据

    这两种方法在适当的上下文中都是有效的,我在数据库设计中使用这两种方法。(我通常倾向于使用候选键来施加多重性,但结果是一样的。)



    您可以使用记号从时间中获取唯一的名称。我已经使用了勾号和随机字符串,然后将它们合并,并为我的文件获取一个唯一的字符串名称。希望能有帮助


    请看一看这个问题,它可能会回答您的问题[[1]:当域小于范围或范围小于域时是否会发生冲突?以及“小于”你的意思是集合中元素的数量,也许澄清这一点会很有用。谢谢@user2864740,我明白你的意思。我想这确实是一个判断,我们的解决方案是否能够承受碰撞,尽管可能性很小。在帖子中,有另一个答案也指出了这一点。@windfly2006想法是碰撞的几率小得难以置信。比如,碰撞的几率比被流星击中的几率小。请参见本章底部的表格。@windfly2006即使是guid也有同样的“几率”复制的问题——所以归结起来就是:数据的散列应该被公开还是应该被公开一个任意的唯一ID?如果散列被公开,人们可以尝试对他们自己生成的散列进行“探测攻击”。感谢@user2864740,我认为GUID(类型1)应该比GUID有更少的复制机会(类型3/5)。不过,我明白你的意思。非常感谢。我们希望在任何给定的时间为同一文件URL获取相同的GUID,因为同一文件URL应该只有一条记录。因此我不确定上述方法是否有效。我认为创建GUID时会考虑时间。我担心你是否可以重新创建GUID。对不起,我想我没有请澄清。我们希望能够为相同的文件URL创建相同的GUID。