我已经阅读了一些关于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”,只要我没有压缩数据库,我保证总能得到相同的答案吗?
答案 0 :(得分:30)
CouchDB最常犯的错误可能是相信它为您的数据提供了版本控制系统。它没有。
压缩会删除所有文档的所有非最新修订,并且复制仅复制任何文档的最新修订。如果您需要历史版本,则必须使用任何对您有用的方案将其保留在最新版本中。
如上所述,“_ rev”是一个不幸的名字,但没有其他任何一个词被提出更清楚。之前已经提出过“_mvcc”和“_mcvv_token”。两者的问题在于,对那里发生的事情的任何描述将不可避免地包括“旧版本保留在磁盘上直到压缩”,这仍然意味着它是用户版本控制系统。回答问题“我可以问CouchDB”在时间t0,ID为1的用户名称是什么?“?”,简答为“否”。长的回答是“是的,但后来它将无法工作”,这只是说“不”的另一种方式。 :)
答案 1 :(得分:4)
回答第二个问题: 是强>
更改的数据始终添加到具有更高版本号的树中。同样的转速永远不会改变。
您的信息:
修订版(1-abcdef)就是这样构建的:1 =版本号(这里:第一版), 第二个是文档内容的哈希(不确定,如果有更多的“盐”)... 因此,当在相同的更改级别(1-,2-,3-)
时,相同的doc内容将始终生成相同的版本号(具有相同的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”:
for (var curRev in doc.versions) {
map([doc.doc_id,doc.versions[curRev].v],doc.versions[curRev]);
}
呼叫:
?/ byRev startkey = [ “5374”]&安培; endkey = [ “5374”,{}]
结果:
{id:“docHistoryContainer_5374”,key = [5374,1] value = {... doc_content v1 ....}} {id:“docHistoryContainer_5374”,key = [5374,2] value = {... doc_content v2 ....}}
Additionaly 您现在还可以编写一个与键中日期相符的地图功能,这样您就可以在日期范围内要求修改
答案 2 :(得分:4)
如前所述,这在技术上是可行的,你不应该指望它。它不仅涉及压缩,还涉及复制,这是CouchDB最大的优势之一。但是,是的,如果您从未压缩,如果您不复制,那么您将能够始终获取所有文档的所有先前版本。我认为它不适用于查询,但它们无法与旧版本一起使用。
基本上,将它称为“rev”是CouchDB设计中最大的错误,它应该被称为“mvcc_token”或类似的东西 - 它实际上只实现了MVCC,它并不意味着用于版本控制。 / p>
答案 3 :(得分:1)
t0(t1 ...)在couchdb中称为“修订版”。每次更改文档时,修订号都会增加。 文档旧版本将被存储,直到您不再需要旧版本,并告诉数据库“compact”。 请查看http://wiki.apache.org/couchdb/HTTP_Document_API
中的“访问以前的修订”