在CouchDB中,我应该使用_id来表示关系和_更改吗?

在CouchDB中,我应该使用_id来表示关系和_更改吗?,couchdb,cloudant,Couchdb,Cloudant,我一直在努力,我该怎么做。老实说,当我开始扩展我的应用程序时,如果我不这么做,我可能会面临一些后果,这让我有点偏执 目前,每个数据库大约有5万个文档。仅仅几个月就被大量使用了。我希望这会增长很多。我做了很多.find()Mango查询,没有太多索引;老实说,我们正在构建一个关系式的文档结构 例如: 首先从ID获取项目 然后执行以下查找查询: 获取所有type:signature其中project\u id:X 获取所有type:revisionswhereproject\u id:X 原

我一直在努力,我该怎么做。老实说,当我开始扩展我的应用程序时,如果我不这么做,我可能会面临一些后果,这让我有点偏执

目前,每个数据库大约有5万个文档。仅仅几个月就被大量使用了。我希望这会增长很多。我做了很多
.find()
Mango查询,没有太多索引;老实说,我们正在构建一个关系式的文档结构

例如:

  • 首先从ID获取项目
  • 然后执行以下查找查询:
    • 获取所有
      type:signature
      其中
      project\u id:X
    • 获取所有
      type:revisions
      where
      project\u id:X
原因是我尽力不更新文档。很多文档都是离线创建的,因此执行一次写入工作流对于避免冲突非常重要

我目前正处于一个无法回头的时刻,因为日程安排变得相当紧张。如果我想改变我现在做事的方式,在事情变得太疯狂之前,这是最好的时机

我很想听听您对使用
\u id
构建数据结构和人们的想法的看法

能够像这样用一个_all_文档抓取器打一个电话对我来说很有吸引力:

{
  "include_docs": true,
  "startkey": "project:{ID}",
  "endkey": "project:{ID}:\ufff0"
}
我的一种文档类型的设置示例如下:

主文档

{
    _id: {COUCH_GENERATED_1},
    type: "project",
    ..
    .
}
{
    _id: {COUCH_GENERATED_2},
    type: "signature",
    project_id: {COUCH_GENERATED_1},
    created_at: {UNIX_TIMESTAMP}
}
{
    _id: {COUCH_GENERATED_3},
    type: "revision",
    project_id: {COUCH_GENERATED_1},
    created_at: {UNIX_TIMESTAMP}
    data: [{..}]
}
签名文件

{
    _id: {COUCH_GENERATED_1},
    type: "project",
    ..
    .
}
{
    _id: {COUCH_GENERATED_2},
    type: "signature",
    project_id: {COUCH_GENERATED_1},
    created_at: {UNIX_TIMESTAMP}
}
{
    _id: {COUCH_GENERATED_3},
    type: "revision",
    project_id: {COUCH_GENERATED_1},
    created_at: {UNIX_TIMESTAMP}
    data: [{..}]
}
更改主文档

{
    _id: {COUCH_GENERATED_1},
    type: "project",
    ..
    .
}
{
    _id: {COUCH_GENERATED_2},
    type: "signature",
    project_id: {COUCH_GENERATED_1},
    created_at: {UNIX_TIMESTAMP}
}
{
    _id: {COUCH_GENERATED_3},
    type: "revision",
    project_id: {COUCH_GENERATED_1},
    created_at: {UNIX_TIMESTAMP}
    data: [{..}]
}

我想知道我是否应该这样做:

主文档
\u id:project:{kuuid\u 1}

签名文件
\u id:project:{kuuid_1}:签名:{kuuid_2}

主文档更改
\u id:project:{kuuid_1}:rev:{kuuid_3}

我只是想用一种不会在将来影响我的方式来建立我的数据库。我知道问题会出现,但如果我能避免的话,我不想大幅改变结构


我想到这一点的另一个原因是,我观察数据库中的
\u变化,并且能够知道发生了什么类型的变化,而不必每次文档发生变化时都获取每个文档,这听起来也很吸引人。

设置数据库结构,使数据检索更容易,这是一种很好的做法。在我看来,你有一些选择:

  • 如果感兴趣的文档中有一个名为
    project\u id
    的字段,您可以在
    project\u id
    上创建一个索引,这样您就可以廉价地获取与已知项目id相关的所有文档。看
  • 创建键入
    project\u id
    的MapReduce索引,例如
    if(doc.project\u id){emit(doc.project\u id)}
    。这样生成的索引将允许您在查询视图时明智地使用
    start\u key
    end\u key
    按已知的项目id获取文档。看
  • 正如您所说,将更多信息打包到
    \u id
    字段中,可以在
    \u all\u docs
    端点上执行范围查询
  • 如果您选择的键设计为:

    project{project_id}:signature{kuuid}
    

    然后,数据库的主索引将单个项目的所有文档分组在一起。将project_id放在“:”字符之前是为即将推出的CouchDB特性“分区数据库”做准备,该特性将逻辑上相关的文档分组到它们自己的分区中,从而使在单个分区(在您的项目中)上执行查询更快、更容易。这个特性还没有准备好,但是它可能有一个
    {partition\u key}:{document\u key}
    格式的
    \u id
    字段,所以当它到达时,为它准备好文档id是没有害处的(请参阅!同时,对_all_docs的范围查询将起作用。

    即使您使用的是CouchDB而不使用PockDB,也可能相关:另请参阅。其源代码将在上下文中显示与上述答案类似的内容。