键值存储:克服键长限制

时间:2014-08-16 08:07:44

标签: memcached couchbase nosql

如何在Key-Value商店中强制执行唯一数据长度超过密钥长度限制的唯一约束?

我目前使用CouchBase存储以下文档:

{
    url: "http://google.com",
    siteName: "google.com",
    data:
    {
       //more properties
    }
}

url + siteName 中定义了唯一约束。但是我不能使用这些属性作为密钥,因为长度可能比CouchBase的密钥长度限制更长。

我目前有两个解决方案,但我认为两者都不够好。


解决方案1 ​​ 文档密钥是 url + siteName 的SHA1哈希。

  • 优点:易于实施
  • 缺点:可能发生碰撞

解决方案2 文档键是哈希( url + siteName )+ 索引。 这与解决方案1相同,但在发生碰撞时,键包括 index

要添加文档,请使用应用程序服务器:

  1. index 设为0
  2. 使用key = hash( url + siteName )+ index
  3. 存储文档
  4. 如果发生重复密钥冲突,请阅读文档
  5. 现有文档是否与我们存储的文档具有相同的 url 网站名称
  6. 如果是,则抛出异常,不允许重复
  7. 如果否,请递增 index 并返回步骤2
  8. 这是目前我最喜欢的解决方案,因为它可以处理冲突

    我是NoSQL n00b!如何在键值存储中强制执行唯一约束?

2 个答案:

答案 0 :(得分:1)

我会选择解决方案1但是为了选择散列函数,您应该考虑以下事项:

  1. 你有多少数据? =>生成的哈希应该有多大,以便将colisions的概率降到最低? - 这里最好的可能是SHA-512,它有512位大输出散列,而SHA-1则是160位
  2. 您需要从散列函数中获得什么性能?与md5相比,SHA-x相当慢,并且根据你要存储的项目数量md5也可能相当不错。
  3. 最后你也可以有一个组合,如果它足够短就使用sitename + url作为键,切换到sitename + hash(url)以防这个组合可以足够短并且最后只有哈希一起

    在相关的说明中我也发现了这个问题http://www.couchbase.com/communities/q-and-a/key-size-limits-couchbasemembase-again,其中一个答案建议在可能的情况下压缩密钥。

    您实际上可以使用普通的gzip压缩并对文本进行编码。我不确定这对你的用例有多好,你必须检查它,但是我用它来制作JSON文件并设法将它降低到~20% - 但它是一个巨大的8MB文件所以压缩你的钥匙的可能性可能要低得多。

答案 1 :(得分:1)

在阅读完您的问题之后,我的想法/意见,我认为应该有助于为选择第一个选项提供理由。

  1. Couchbase是内存缓存/字典。要存储许多(读取“非常大的难以理解的数字”)值,它需要RAM和磁盘空间。无论每个文档占用多少空间,所有文档密钥都存储在RAM中。如果您因此被允许为密钥存储任意大的值,那么您的服务器场将比您提供的RAM更快地消耗RAM,并且您的设计将崩溃。

  2. 在第1项的情况下,您的应用程序需要设计为使密钥大小尽可能小。字典键/哈希值计算取决于应用程序API(与将其留给.Net或Java API的方式相同 - 它同样计算字符串输入的哈希值)。为了保持一致性,无论输入如何,都应使用相同的方法来生成散列。

  3. SHA1具有极低的冲突概率,它的设计方式使加密的“破坏”在计算上不可行。这是比特币“指纹”背后的基础。有关此主题的美味阅读,请参阅herehere

  4. 鉴于我对哈希的了解,并且考虑到URL总是以相同的字符集开头,这在理论上会进一步降低发生冲突的可能性。

  5. 实际上,如果您存储足够的文档以确定SHA1冲突的可能性很大,那么几乎可以肯定至少有十几个其他问题会以更显着的方式影响您的应用程序的可用性和可靠性你应该全神贯注地思考这些事情。

  6. 成为一名工程师的困难之处在于认识到需要从工程中退后一步,并说“好”是“足够好”。话虽这么说,选项1看起来是最好的选择,它简单而且一致。如果使用得当,那就是您所需要的。选中此框上的复选框,然后转到下一期。