13

我发现在网站上显示数据时使用 CouchDB 附件非常有用。但是,当我将数据库复制到移动环境时,运行视图然后必须循环浏览文档以访问其附件的效率非常低。在 iOS/Android 平台上,将数据存储为常规 BLOBS 并通过一个视图查询访问所有二进制数据似乎更有效,视图查询首先发出所有文档数据。有没有办法在我的地图函数中读取附件数据,并将其包含在发出语句中。我看到可以通过 _attachments 获得附件信息,但这并不能访问数据。

更新 在文档本身而不是附件中使用 BLOBS 的一个主要缺点(未在接受的答案中详述)是,当您更新文档时,您必须获取整个文档,然后将其发布回来。如果您不使用附件,则必须获取所有二进制数据,而附件则不需要。如果您要对文档执行更新,那么使用附件确实是设计二进制数据的唯一合理方法。

4

1 回答 1

16

你遇到了一个很好的问题!

什么是附件?

是二进制数据吗?好吧,您可以对数据进行 Base64 编码并将其直接存储在文档中(类似于数据 URI)。你当然可以有文本或应用程序/json 附件。所以不是这样。

是直接下载吗?并不真地。显示和列表功能让您可以直接提供文档的任何部分(或基于文档数据构建新内容)。

那么什么附件呢?对我来说,附件的工作定义是在视图、显示和列表中无法访问的数据。这是一种优化。您无法从服务器端 Javascript 访问它;但是您获得了速度,因为 CouchDB 不必对大量数据进行编码和解码。

有时我也将其视为 C 指针。使用指针非常快。它们是一种小型、简单的数据类型。然而,代价是额外的编程工作,因为它们必须被取消引用才能获取数据。你总是有一个额外的步骤。这就是速度的代价。CouchDB 附件是类似的。

如果您的数据很小(可能是网站图标、电子名片、文本)并且适合整个文档,那就去做吧!不要附加它们。但是,对于大多数图像和其他文件等较大的数据,附件就变得必要了。

多次提取

假设您查询一个视图并在屏幕上显示 20 行。现在您必须获取 20 个图像附件。

程序员本能地认为这是不可取的。而且,是的,这可能会破坏交易。然而,在许多情况下,这是一个很好的权衡。Donald Knuth 说:“过早的优化是万恶之源。” 从由 SSD 支持的本地服务器进行 21 次总提取会杀死我们吗?

在许多情况下,进行 20 次查询就可以了。关键是同时制作它们。CouchDB(和移动沙发库)针对并发请求进行了优化。你会发现获取 20 张图片与获取一张图片所花费的时间基本相同。

在每种语言中,同时获取 HTTP 资源的工作方式不同。在 Javascript 中,这非常简单,只需要几行带有async.js的代码。

// Assuming fetch_image(), and images = ['alice.png', 'bob.png',  etc.]
async.forEach(images, fetch_image, function(er) {
  if(er) throw er
  console.log('Fetched 20 images!')
})
于 2012-04-06T00:08:13.917 回答