【问题标题】:Is it good practice to give each CouchDB user a separate database?给每个 CouchDB 用户一个单独的数据库是一种好习惯吗?
【发布时间】:2015-04-16 19:02:27
【问题描述】:

我有一点关于用户及其文档结构的概念性问题。

为 CouchDB 中的每个用户提供保存其文档的自己的数据库是否是一种好习惯?

我了解到 couchDB 可以处理数千个数据库,并且每个用户拥有自己的数据库并不少见。

原因:

问这个问题的原因是我正在尝试创建一个系统,其中登录用户只能查看他们自己的文档,而不能查看任何其他用户的文档。

任何建议。

提前谢谢你。

【问题讨论】:

    标签: javascript database couchdb couchdb-futon


    【解决方案1】:

    这是一个很常见的用例,尤其是在移动环境中,每个用户的数据都使用 Android、iOS 或 JavaScript (pouchdb) 库之一同步到设备。

    所以在概念上,这很好,但我仍然建议在投入生产之前彻底测试。

    请注意,多个数据库的一个缺点是您不能编写跨多个数据库的查询。不过也有一些变通方法 - 有关更多信息,请参阅 Cloudant: Searching across databases


    2017 年 3 月 17 日更新

    有关此方法的更多信息,请查看 Cloudant Envoy。

    每用户数据库是 CouchDB 的一种常见模式,当需要每个应用程序用户拥有自己的一组可以同步的文档时(例如到移动设备或浏览器)。从表面上看,这是一个很好的解决方案——Cloudant 可以在一次安装中很好地处理大量数据库。不过……

    来源:https://github.com/cloudant-labs/envoy

    【讨论】:

    • 非常感谢您的回复。是否有另一种方法可以防止用户查看数据库中的其他文档。这可以通过数据库设计文档中的“视图”map/reduce函数对数据进行排序来实现吗?
    【解决方案2】:

    为每个用户创建 CouchDB 存储桶 (DB) 是相当常见的场景。虽然有一些缺点:

    • 您必须使每个用户存储桶中的 ddoc 保持同步,因此跨多个存储桶部署 ddoc 更改可能会成为真正的冒险。
    • 如果文档以某种方式在用户之间共享,您会在每个存储桶中获得 doc 和 viewindex 副本。
    • 您必须阻止 _info 请求以避免用户列表泄漏(或者您必须使用哈希命名存储桶)。
    • 在任何情况下,您都需要在 Couch 前使用一些代理来创建和准备用户注册时的新存储桶。
    • 您可以更好地保护 Couch 在接收到许多请求时不会出现容量不足 - 它还需要代理。

    可以使用_list 函数来实现按文档读取 ACL,但是这种方法有一些缺点,并且它还需要在 CouchDB 前面有一个代理,至少是一个 Web 服务器。详情请见CouchDb read authentication using lists

    您也可以尝试使用CoverCouch,它实现了完整的按文档读取 ACL,保持原始 CouchDB API 不变,但它还处于早期测试阶段。

    【讨论】:

    • 这种方法的弊大于利:您最终将完全失去对您的网站和数据的控制。即使知道最近注册了多少用户,如果不是不可能的话,也可能是一场噩梦,用这种方法!!!
    • @mlorini:你说的是哪种具体方法?这个答案涉及几个选项。
    【解决方案3】:

    为多个用户使用多个数据库有一些重要的缺点:

    • 使用原生 couchdb API 无法查询不同数据库中的数据。 分析您网站的整体状态是不可能的!
    • 维护很快就会变得非常困难:让我们想想每次要执行备份时复制/压缩数千个数据库

    这取决于您的用例,但我认为一个不错的方法可以是:

    1. 只允许通过虚拟主机访问。这可以使用代理或更简单地通过使用couchdb hosting 提供程序来实现,它可以让您微调您的“域->路径”映射

    2. 使用 design docs / couchapps,而不是直接的文档 CRUD API,进行读/写操作

      2.1。使用 _rewrite 处理程序仅允许有效请求:通过这种方式,您可以立即阻止对 _all_docs、_all_dbs 等合理处理程序的访问

      2.2。将 _list_view 处理程序用于 read doc/role based ACL,如CouchDb read authentication using list

      中所述

      2.3。使用 _update 处理程序来编写基于文档/角色的 ACL

      2.4。对基于角色的读/写 ACL 使用经过身份验证的重写规则。

      2.3。 过滤的 _changes 处理程序 是另一种使用基于读取文档/角色的 ACL 检索所有用户数据的方法。根据您的用例,这可以有效地尽可能简化您的读取 API,让您专注于更新 API。

    【讨论】:

    • 这种方法不好,因为 a) 列表转换本质上很慢,b) 以这种方式实现附件的访问控制是不切实际的 – _list 解析 base-64 JSON 附件在每个请求上,都会占用 CPU 和 RAM。
    • 肯定比view+list快——因为我们只执行一次json序列化。让我解释一下 view+list 是如何工作的,以及它与直接查看请求有何不同。 View 以块的形式返回数据——如果你有 10 行回复,你会收到 12 个(或更多)块。请注意,您很快就会收到第一个块。 View+list 首先收集整个序列化的视图响应,然后再次解析它,然后执行列表,然后再次序列化。当然,它不可避免地很慢。
    • 关于使用不可猜测 ID 的安全性 - 请阅读本文papers.ssrn.com/sol3/papers.cfm?abstract_id=842228。默默无闻的安全是一种幻想。
    • 它既不快也不高效——我有几个系统使用这种方法,并且有 2 年的统计数据。使用此架构您构建服务器,花费大部分 RAM 和 CPU 来解析 ACL。对于小型系统(例如数十个用户)来说这是合理的,因为即使是最小的 VPS 也绰绰有余。但即使对于中等容量的系统,这种方法也太浪费了。
    • 亲爱的@mlorini,当然浏览量很快。但是像 view+list 这样的链通常要慢得多。不管你是否同意,因为这个事实很容易被测试和衡量。 因此,如果您想为中型和大型系统提供高效的按文档读取 ACL,请在 CouchDB 之外实现它。 请到此为止。
    【解决方案4】:

    该解决方案与 Web 应用程序一样古老 - 如果您想到一个 mySQL 数据库,那么数据库中没有任何内容可以阻止用户 B 查看属于用户 A 的记录 - 它都是在应用程序层中编码的。

    在 CouchDB 中,同样没有完全安全的方法来阻止用户 B 访问用户 A 编写的文档。您需要像以前一样在应用程序层中对此进行编码。

    如果您在 CouchDB 和用户之间有一个 Web 应用程序,那么您就没有问题。当您允许 CouchDB 直接处理请求时,问题就出现了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-02-04
      • 2017-08-09
      • 2017-09-27
      • 1970-01-01
      • 2017-03-09
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多