Доступны ли старые данные в 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