Доступны ли старые данные в CouchDB?
Я немного читал о CouchDB, и я действительно заинтригован тем, что он "append-only". Возможно, я ошибаюсь, но, как я понимаю, он работает примерно так:
-
данные добавляются в момент времени t0 в БД, сообщая, что пользователь с именем ID 1 является "Cedrik Martin"
-
запрос с запросом "что такое имя пользователя с идентификатором 1?" возвращает "Cedrik Martin"
-
в момент t1 в БД происходит обновление: "Имя пользователя с идентификатором 1 - это Cedric Martin" (изменение "k" на "c" ).
-
запрос с запросом "имя пользователя с идентификатором 1" теперь возвращает "Cedric Martin"
Это глупый пример, но это потому, что я хотел бы понять что-то фундаментальное в CouchDB.
Видно, что обновление было выполнено с помощью добавления в конце БД, возможно ли запросить БД "как это было в момент времени t0", не делая ничего особенного?
Могу ли я спросить CouchDB "Каково было имя пользователя с идентификатором 1 в момент времени t0?"
РЕДАКТИРОВАТЬ первый ответ очень интересный, и поэтому у меня есть более точный вопрос: до тех пор, пока я не "уплотняю" CouchDB, я могу писать запросы, которые каким-то образом "ссылаются" прозрачный "(т.е. они будут всегда выдавать тот же результат)? Например, если я запрашиваю" document d при ревизии r", я гарантированно всегда получаю тот же ответ, если я не уплотняю БД?
Ответы
Ответ 1
Возможно, наиболее распространенная ошибка, допущенная с помощью CouchDB, заключается в том, чтобы полагать, что она предоставляет систему управления версиями для ваших данных. Это не так.
Уплотнение удаляет все не самые последние версии всех документов, и репликация только реплицирует последние версии любого документа. Если вам нужны исторические версии, вы должны сохранить их в своей последней редакции, используя любую подходящую вам схему.
"_ rev", как отмечалось, является неудачным именем, но не было предложено ни одного другого слова, которое было бы более ясным. "_mvcc" и "_mcvv_token" были предложены ранее. Проблема в том, что любое описание того, что происходит там, неизбежно будет включать в себя "старые версии остаются на диске до уплотнения", которые все равно будут подразумевать, что это система управления версиями пользователей.
Чтобы ответить на вопрос "Могу ли я спросить CouchDB" Каково было имя пользователя с идентификатором 1 в момент времени t0??? ", короткий ответ" НЕТ ". Длинный ответ:" ДА, но потом это не сработает ", что является еще одним способом сказать" НЕТ".:)
Ответ 2
Как уже говорилось, это технически возможно, и вы не должны рассчитывать на это. Речь идет не только о уплотнении, но и о репликации, одной из самых сильных сторон CouchDB. Но да, если вы никогда не компактны, и если вы не реплицируете, вы сможете всегда извлекать все предыдущие версии всех документов. Я думаю, что это не сработает с запросами, но они не могут работать со старыми версиями.
В принципе, называть его "rev" была самая большая ошибка в дизайне CouchDB, его следовало называть "mvcc_token" или что-то в этом роде - она действительно реализует MVCC, она не предназначена для использования в версиях.
Ответ 3
Ответ на второй вопрос:
Да.
Измененные данные всегда добавляются к дереву с более высоким номером ревизии. тот же оборот никогда не изменяется.
Для информации:
Эта ревизия (1-abcdef) построена таким образом: 1 = номер версии (здесь: первая версия),
во-вторых, хеш над содержимым документа (не уверен, если там есть еще "соль" )...
поэтому в одном и том же содержимом документа всегда будет одинаковый номер версии (с той же настройкой couchdb) даже на других машинах, когда на одном и том же уровне изменения (1-, 2-, 3-)
Другой способ: если вам нужно хранить старые версии, вы можете хранить документы внутри большего документа:
{
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....}}
Дополнительно теперь вы можете написать также функцию-карту, которая использует дату в ключе, поэтому вы можете запросить изменения в диапазоне дат
Ответ 4
t0 (t1...) находится в couchdb, называемом "ревизия". Каждый раз, когда вы меняете документ, количество изменений увеличивается.
Старые версии документов хранятся до тех пор, пока вы больше не захотите иметь старые версии и сообщите базе данных "compact".
Посмотрите на "Доступ к предыдущим версиям" в http://wiki.apache.org/couchdb/HTTP_Document_API