【问题标题】:Is there anything wrong with creating Couch DB views with null values?使用空值创建 Couch DB 视图有什么问题吗?
【发布时间】:2012-01-29 21:05:50
【问题描述】:

我最近在业余时间一直在使用 Couch DB 进行大量工作,并且非常喜欢使用它。我发现它比使用关系数据库灵活得多,但也不是没有缺点。

一个很大的缺点是缺少动态查询/视图生成...因此,您必须做大量工作来规划和证明您的视图,因为您不能像您可能的那样将该逻辑放入您的应用程序代码中使用 SQL。

例如,我基于一个 JSON 文档模板编写了一个登录方案,看起来有点像这样:

{ 
   "_id": "blah",
   "type": "user",
   "name": "Bob",
   "email": "bob@theaquarium.com",
   "password": "blah",
}

为了防止创建重复帐户,我编写了一个非常基本的视图来生成用户名列表以作为键查找:

emit(doc.name, null) 

这对我来说似乎相当有效。我认为这比拖出整个文档列表(甚至只是减少每个文档的字段数量)要好得多。所以我做了完全相同的事情来生成一个电子邮件地址列表:

emit(doc.email, null)

你知道我要回答这个问题吗?

在关系数据库(使用 SQL)中,只需对同一张表进行两次查询。这种技术(将视图等同于 SQL 查询的结果)在某种程度上是否类似?

然后是性能/效率问题......这两个视图真的应该只是一个吗?还是使用带有键且没有关联值的 Couch DB 视图是一种有效的做法?考虑到上面的例子,这两个视图都会在登录方案之外使用......如果我需要生成用户名列表,我可以在没有额外开销的情况下检索它们。

你怎么看?

【问题讨论】:

  • 使用emit(doc.name, null) 构建视图类似于在SQL 表的name 列上构建索引。所以这与您在关系数据库中所做的没有什么不同。

标签: views nosql couchdb mapreduce document-oriented-db


【解决方案1】:

首先,您当然可以将视图逻辑放入您的应用程序代码中——您所需要的只是一个适当的构建或部署系统,该系统从应用程序中提取视图并将它们添加到设计文档中。缺少的是动态生成新查询的能力。

您的emit(doc.field,null) 方法当然并不令人惊讶或不寻常。事实上,这是“按字段查找文档”查询的常用模式,其中使用include_docs=true 提取文档。也没有必要将两个视图混合为一个,唯一与性能相关的决定是这两个视图是否应该放在同一个设计文档中:设计文档中的所有视图在访问它们时都会更新。

当然,您的方法实际上并不能保证电子邮件是唯一的,即使您的应用程序非常努力。想象以下情况,有两个客户端应用程序 A 和 B:

A: queries view, determines that `test@email.com` does not exist.
B: queries view, determines that `test@email.com` does not exist.
A: creates account with `test@email.com`
B: creates account with `test@email.com`

这是一种罕见的情况,但仍有可能。更好的方法是保留使用电子邮件地址作为密钥的文档,因为对单个文档的访问是事务性的(不可能使用相同的密钥创建两个文档)。典型例子:

{
  _id: "test@email.com",
  type: "email"
  user: "000000001"
}

{
  _id: "000000001",
  type: "user", 
  email: "test@email.com",
  firstname: "Test", 
  ...
}

编辑:仅当尝试为给定电子邮件创建帐户的两个客户端将可靠地尝试访问 same 文档时,保留模式才有效。如果您随机生成一个新标识符,那么客户端 A 将创建并保留文档 XXXX,而客户端 B 将创建并保留文档 YYYY,您最终将得到两个具有相同电子邮件的不同文档。

同样,执行事务性“检查是否存在,如果不存在则创建”操作的唯一方法是让所有客户端更改单个文档。

【讨论】:

  • 在主/主场景中无法保证唯一性。您需要管理冲突。
  • ...或者有一个单一的主人来执行唯一性文件。
  • 当然可以,但是您应该清楚地说明以避免混淆。 Master/master 设置是 CouchDB 的卖点之一。那么最好知道它是有代价的。
  • 啊...我现在了解唯一ID/唯一字段文档方法。我在这里找到了更多详细信息:kfalck.net/2009/06/29/enforcing-unique-usernames-on-couchdb。该链接还提供了有关如何将这些独特字段推送到多主集群上的横向数据库实例的建议。感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2014-04-01
  • 2011-08-17
  • 2015-02-10
  • 2012-01-11
  • 1970-01-01
  • 2013-10-02
  • 2011-07-03
  • 1970-01-01
相关资源
最近更新 更多