每个用户数据库 (pouchdb/couchdb) 和共享数据 - 可行吗?

per user db (pouchdb/couchdb) & shared data - doable?

我有以下用例/应用程序:

一个 TODO 应用,用户可以在其中:增删改查他们的 TODO(我正在使用 pouchdb/couchdb 同步)。很大程度上基于 Josh Morony 的 tutorial

现在我想将用户的能力添加到 "share"(仅限 post,没有 "edit"/put)他们的 TODO 项目与其他用户,谁能够只查看(读取)那些(没有写入权限等)。

我正在考虑添加一个单独的数据库(我们称之为 "shared TODOs DB"),我的服务器可以在其中写入,而所有用户只能读取。 因此,任何用户都可以在该只读数据库中执行 .find() 操作,而 post 根据用户请求共享他们的 TODO,进入其中仍将由服务器管理。

是否有已知的模式(方法)?有没有真正的应用程序/示例已经这样做了?

因此,对于此类项目,每个用户数据库是您的数据库的推荐模式。

想法

所以基本上,您将拥有:

  • 每个用户一个私人数据库(具有 write/read 权限)
  • 一个中央数据库只读

至于中央数据库,你需要它是只读的,你还需要只允许共享文件。为此,您需要某种应用程序代理。您基本上可以在中央数据库之上构建一个 API 并只允许访问共享文档。

然后,您可以设置从每个用户数据库到中央数据库的复制,并在 _replicator 数据库中保留复制。

沙发用户

我不确定每个用户的数据库插件目前是否适用于 2.X.X 版本,但您可以通过某种应用程序流程自行完成(创建用户,然后创建数据库, 然后管理新数据库的权限)

CouchDB 没有提供执行此操作的好方法,但如果您的后端有维护大量共享数据库的工具(除了单用户数据库),我认为您可以实现它。

最初的冲动是使用连续过滤复制 to/from 中央 "master" 集线器,但这给您带来了两个问题:

  • 复制不能删除文档,除非它们被删除! IE。过滤复制并不能确定哪些文档存在目标中,而是确定文档的更改是否会传播 目标。这样的效果是可以分享,但是不能取消分享。
  • 这种复制无法扩展。对于需要保持同步的 N 个用户数据库,中央数据库的每次更改都会强制所有 N 个复制独立处理该更改。现在考虑在中央数据库上发生的更改量 M 几乎与 N 成正比(即,您拥有的用户越多,所有这些用户将不得不更频繁地处理对中央数据库的更改!)您可以稍微减轻这种情况通过添加更多层(从一个中央集线器散开到半共享集线器再到单个数据库),但这也增加了实际的复杂性。

您的分享是如何组织的?您可以做的是为每个 "share" 组合设置一个共享 数据库

当用户A要与用户B共享文档D时,"move"将该文档导入到一个新的数据库AB中。实际上这意味着:将 D 的内容复制到数据库 AB 中的新文档 D',然后从数据库 A 中删除原始 D。

如何同步?

请记住,PouchDB 客户端可以复制 to/from 多个源数据库,因此用户 A 将从 A 和 AB 复制,而用户 B 从 B 和 AB 复制。诀窍是在 相反 方向使用过滤复制,回到服务器数据库:

现在共享的文档 D' 不应进入数据库 A 或数据库 B,同样,未共享的文档 X 不应进入数据库 AB。像这样:

┌───────────────────────┐                                  
│  server:5984/user_a   │                                  
└───┬───────────────▲───┘                                  
    └─┐           ┌─┘    ┌──────────────────────────────┐  
      │           ●──────│ if (doc.shared_with == null) │  
    ┌─▼───────────┴─┐    └──────────────────────────────┘  
    │     local     │                                      
    └──▲──────────┬─┘                                      
     ┌─┘          └─┐      ┌──────────────────────────────┐
     │              ●──────│ if (doc.shared_with == 'ab') │
 ┌───┴──────────────▼────┐ └──────────────────────────────┘
 │ server:5984/shares_ab │                                 
 └───────────────────────┘              

因此,假设已经设置了共享数据库,当本地客户端想要共享一些数据时,它实际上将 _deleted:true 添加到原始(未共享)文档并创建一个新的(共享)文档。删除的原始传播到服务器上的 user_a 数据库,创建的副本传播到 shares_ab.

Unsharing 然后的工作方式几乎相同:客户端将 _deleted:true 添加到 shared 文档并在新的未共享副本中再次重新创建数据。从 B 的角度来看,该文档曾经出现在 shares_ab 中,现在消失了,因为它已从 shares_ab.

中删除

(代替用户 "pairs",您可以将其扩展到临时用户集,或将其简化为用户已经在的特定组,等等。关键思想是创建一个实际共享的所需的每个唯一共享上下文的数据库。)