在CouchDB中是否可以访问旧数据?

在CouchDB中是否可以访问旧数据?,couchdb,append,Couchdb,Append,我读过一些关于CouchDB的文章,我对它是“仅附加”的事实很感兴趣。我可能误解了这一点,但据我所知,它的工作原理有点像这样: 数据在时间t0添加到数据库,告知ID为1的用户的名字是“Cedrik Martin” 询问“ID为1的用户的姓名是什么?”的查询返回“Cedrik Martin” 在t1时刻,数据库被更新,告知:“ID为1的用户的名字是Cedric Martin”(将“k”改为“c”) 再次询问“ID为1的用户的姓名”的查询现在返回“Cedric Martin” 这是一个愚蠢的例子

我读过一些关于CouchDB的文章,我对它是“仅附加”的事实很感兴趣。我可能误解了这一点,但据我所知,它的工作原理有点像这样:

  • 数据在时间t0添加到数据库,告知ID为1的用户的名字是“Cedrik Martin”

  • 询问“ID为1的用户的姓名是什么?”的查询返回“Cedrik Martin”

  • 在t1时刻,数据库被更新,告知:“ID为1的用户的名字是Cedric Martin”(将“k”改为“c”)

  • 再次询问“ID为1的用户的姓名”的查询现在返回“Cedric Martin”

这是一个愚蠢的例子,但这是因为我想了解CouchDB的一些基本知识

如果看到更新是使用数据库末尾的附加进行的,那么是否可以在不做任何特殊操作的情况下“按照时间t0的原样”查询数据库

我可以问CouchDB“在t0时ID为1的用户的名字是什么?”

编辑第一个答案非常有趣,因此我有一个更精确的问题:只要我没有“压缩”CouchDB,我就可以编写某种程度上“引用透明”的查询(即它们总是产生相同的结果)?例如,如果我查询“修订r时的文档d”,只要我不压缩数据库,我是否保证总能得到相同的答案?

t0(t1…)在couchdb中称为“修订”。每次更改文档时,修订号都会增加。 文档的旧版本将被存储,直到您不再需要旧版本,并告诉数据库“compact”。
查看第二个问题的答案中的“访问以前的修订版”: 是。

更改的数据始终添加到修订号较高的树中。同样的版本永远不会改变

有关您的信息:

修订版(1-abcdef)是这样构建的:1=版本数(此处为第一个版本), 第二个是对文档内容的散列(不确定是否还有更多的“盐”。。。 因此,当处于相同的更改级别(1-、2-、3-)时,即使在其他机器上,相同的文档内容也会始终生成相同的修订号(使用相同的couchdb设置)

另一种方法是:如果需要保留旧版本,可以将文档存储在更大的文档中:

{
 id:"docHistoryContainer_5374",
 "doc_id":"5374",
 "versions":[
   {"v":1,
    "date":[2012,03,15],
    "doc":{ .... doc_content v1....}
   },
   {"v":2,
    "date":[2012,03,16],
    "doc":{ .... doc_content v2....}
   }
 ]
}
然后,您可以要求修改:

查看“byRev”:

电话:

/byRev?开始键=[“5374”]&结束键=[“5374”,{}]

结果:

{id:“docHistoryContainer_5374”,key=[5374,1]value={…doc_content v1..} {id:“docHistoryContainer_5374”,key=[5374,2]value={…doc_content v2….}


另外您现在还可以编写一个映射函数来修改键中的日期,因此您可以要求在日期范围内进行修改

正如前面所说的,这在技术上是可行的,您不应该指望它。它不仅涉及压缩,还涉及复制,这是CouchDB最大的优势之一。但是,是的,如果您从不压缩并且不复制,那么您将能够始终获取所有文档的所有以前版本。我认为它不能用于查询,但是,它们不能用于旧版本


基本上,将其称为“rev”是CouchDB设计中最大的错误,它应该被称为“mvcc_token”或类似的东西——它实际上只实现mvcc,并不用于版本控制。

CouchDB最常见的错误可能是相信它为您的数据提供了一个版本控制系统。事实并非如此

压缩将删除所有文档的所有非最新版本,复制仅复制任何文档的最新版本。如果需要历史版本,则必须使用任何您认为合适的方案将其保存在最新版本中

如前所述,“_rev”是一个不幸的名字,但没有其他更清楚的词。此前已建议使用“\u mvcc”和“\u mcvv\u令牌”。两者的问题在于,任何对正在发生的事情的描述都不可避免地包括“旧版本保留在磁盘上直到压缩”,这仍然意味着它是一个用户版本控制系统


要回答问题“我可以问CouchDB”在时间t0时ID为1的用户的名字是什么?“,简短的回答是“否”。长长的回答是“是的,但是以后它就不行了”,这只是说“不”的另一种方式:)

+1。。。这很有趣。我对我的问题进行了更多的编辑:基本上,我想知道查询是否可以变得具有引用透明性(当指定了一个特定的修订时)。天哪,这太大了!因此,只要您不使用compact,并且只要您在与当前日期“小于或等于”的日期范围内进行查询,就可以保证您的查询是引用透明的?(至少在特定数据库的概念中)我认为这是一个惊人的特性!它有可能使“重新创建状态”变得越来越容易(例如在跟踪/调试时)。简单地说,好吧,更容易对整个计划进行推理。这肯定让我对CouchDB非常感兴趣:)+1两个答案:)对不起。。。日期查询仅在第二个版本中。。。无法编写查找旧版本内容的映射。您只能“询问”特定文档的修订,然后检索此修订的内容,但不能查询此链接可能对您有用。
for (var curRev in doc.versions) {
  map([doc.doc_id,doc.versions[curRev].v],doc.versions[curRev]);
}