为面向文档的数据库设计记录密钥 - 最佳实践

时间:2014-01-17 08:47:44

标签: database-design nosql couchbase document-oriented-db

我们的团队已开始开发由Couchbase DB支持的应用程序;对于我们每个人来说,这是第一次使用无SQL数据库的经验。

我们已经开始定义我们的实体,并采用Couchbase手册建议的使用“类型”前缀的做法:

Entity "A":
key: a#123

Entity "B":
key: b#123

但我们意识到我们对选择创建复合文档密钥的策略感到困惑。我们经常使用计数器,他们需要自己的文件。我们的钥匙变得复杂了:

Daily counter "x" for entity "A":
key: cntrx#a#123-20140117

我们已经考虑了不同的方法,但我们仍然是关于这个主题的绿色角色,并想提出一些建议。

分层键是否有用?任何人都可以分享他们定义非平凡键的最佳实践吗?

2 个答案:

答案 0 :(得分:4)

在我们的项目中,我们以下面描述的方式使用分层键: 键的第一部分类似于RDBMS中的表名: users - 代表“表格”

然后每个用户在示例中都有自己的id:

users:1 - “代表一个用户”

我们使用':',因为我认为它看起来比其他分隔符更好。您可以使用任何您喜欢的分隔符。

如果你想在前面的例子中使用像id这样的顺序索引,你需要从某个键获取它们,所以:

users:counter - 包含“最后一个用户ID”的密钥(它的作用类似于自动增量)

如果您需要为用户帐户存储一些“子部分”,您可以存储它:

users:<user's id>:subsection

更复杂的例子

users:1:avatars:1:url - 意味着通过此键我们将获得用户1的头像网址,但如果用户想要存储多个头像,则会将其置于users:1:avatars:X:url下,其中X的值为{ {1}}密钥。

我们将此策略用于所有文档,只存储一个值,JSON甚至二进制数据。

所以完全按照你的例子,我会选择:

users:1:avatars:counter - 这意味着我们(用RDBMS语言说)表名为“a”,在表“a”中我们有id(或其他)的记录“123-20140117”有字段“cntrx”。

<强> UPD: 关于密钥大小。实际上没关系。是键的大小有限,但有很多方法可以减少它。其中之一 - 使用哈希,但我认为这是不好的方式,因为密钥会很长并消耗更多内存。在我们的项目中,我们使用memcached bucket的“短”键。我们有一个枚举(也可以存储在couchbase中),它代表了人类可理解的密钥名称,并缩短了它的价值。

示例:我们有一些记录集:拥有超过30张照片的用户列表。 所以我们有一个键值对:

a:123-20140117:counter

对于30张照片,密钥为 usersByPhotosCount - k:ubpc:{0}

但最好只在生产上进行此类优化。在开发中,最好在应用程序和数据库中使用可理解的密钥(即,您可以创建两组k-v对:开发正常,生产时缩短和混淆,并根据您的环境加载它们。)

答案 1 :(得分:2)

关于你的问题我有几点建议。

总体

Nosql就像它听起来一样 - 并且需要一种与之前用于设计良好SQL数据库的思维方式截然不同的思维方式。例如,一个nosql数据库基本上是一个大的哈希映射。因此,尽管将思想放入密钥(例如将其缩小)可能会很好,但请记住,它们只是访问文档的一种方法。除非从某种方式看起来具有一些特定的优势,否则它们根本不需要任何意义 - 通常总是需要首先进行主要查找。举个例子,您的用户多久知道他们需要在导航到您的应用时直接询问“b#123”?我能想到的唯一有利于用户会知道的用户名或其他数据。

复合键

虽然CB手册可能表明复合键是一个好主意(并且它们很可能适用于简单的数据库结构),但一般来说,密钥大小应该尽可能小。密钥限制为最多256个字节。所有密钥必须存储在RAM中 - 因此密钥中的数据越多,其余数据的可用性就越小。相反,我建议在文档中创建一个类型字段,然后使用视图提取特定类型的对象(或按类型索引对象)。这将最终为您提供更大的灵活性。

计数器

您对计数器的解释相当模糊,因此我假设您将它们用作自动增量键。我建议这里需要改变方法以摆脱反击。我为数据库中的所有键使用唯一标识符。当我使用复合键时,这是因为密钥本身很重要(例如,在修订控制的文档中,我使用文档id的复合键+文档保存的日期以确保它是唯一的)。即使您有数百万(甚至数十亿)个对象,也可以使用12个字节的GUID来实际保证文档ID的唯一性。这可以防止在需要保存新记录时应用程序中出现非常糟糕的瓶颈。