在couchdb中建模图形的含义

Ric*_*mon 6 couchdb graph data-modeling

我一直在使用couchdb中的图形结构(具有命名关系的属性图)建模,并想知道我会发现什么是性能的潜在瓶颈.

我使用以下原则:

  • 保持文件小.
  • 尝试尽可能少地嵌入.
  • 将文档之间的所有关系记录为新文档(链接).

似乎所有这些原则都与CouchDB哲学相矛盾,

例如,有了这个原则,标记一个人就成了三个文件:

{ _id: '10', type: 'person', 'name': 'John Doe' }
{ _id: '20', type: 'tag', 'name': 'Important' }
{ _id: '30', type: 'link', from: 10, to: 20, name: 'tag' }
Run Code Online (Sandbox Code Playgroud)

我还在一个_design名为的文档中创建了以下视图links:

{
  outgoing: {
    map: function(doc) {
      if (doc.type == 'link') {
        emit([doc.from, doc.name], {_id: doc.to});
      }
    }
  },
  incoming: {
    map: function(doc) {
      if (doc.type == 'link') {
        emit([doc.to, doc.name], { _id: doc.from });
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我可以通过这些网址获取文档传入或传出的所有链接:

http://host/db/_design/links/_view/incoming?startkey=["10"]&endkey=["10",{}]
http://host/db/_design/links/_view/outgoing?startkey=["10"]&endkey=["10",{}]
Run Code Online (Sandbox Code Playgroud)

我甚至可以通过这些网址获取所有名称的链接:

http://host/db/_design/links/_view/incoming?startkey=["10","tag"]&endkey=["10","tag",{}]
http://host/db/_design/links/_view/outgoing?startkey=["10","tag"]&endkey=["10","tag",{}]
Run Code Online (Sandbox Code Playgroud)

如果我包含include_docs=true参数,我会得到链接引用的文档; 传入或传出.到现在为止还挺好.有一个图结构和查询它的方法,虽然是逐个节点.

关于这种方法的好处:

  • 这是存储所有关系的一般方式.不一定是标签,而是每个关系.
  • 您可以快速更改标记名称,而无需更改标记的每个人.
  • 您可以合并人员或标签,只需更新link文档,这应该非常简单.
  • 使用复制时进行标记不会更改标记的文档或标记本身.只需添加或删除一个小link文档.
  • 保留每个元素的标记历史很容易.

糟糕的事情,以及我需要你帮助的地方:

  • 查询带有标签的人员列表并非易事.通常,查询文档列表及其关系是一项非常昂贵的操作,需要很多命中.
  • 更新数据库并保持一致可能是个问题.也许这是使用沙发时永远不会消失的东西.
  • 对数据库进行"维护",例如查找孤立链接,可能会很昂贵.也许数据库需要垃圾回收?
  • 可视化和操作此图形结构既不直观也不简单,并且在其上开发的应用程序负责所有图形结构管理(这有点可怕!).

回到我的问题:

  1. 期待的潜在瓶颈是什么?
  2. 这种方法会扩展到数百万条记录吗?
  3. 如何有效地遍历此结构而无需执行多次服务器命中?