2012-03-16 11 views
11

Ho letto un po 'di CouchDB e sono davvero incuriosito dal fatto che sia "solo append". I può essere equivoco che, ma se ho capito bene, funziona un po 'come questo:I vecchi dati sono accessibili in CouchDB?

  • dati vengono aggiunti al momento t0 al DB dicendo che un utente con il nome ID 1 è "Cedrik Martin"

  • una domanda che chiede "qual è il nome dell'utente con ID 1?" restituisce "Cedrik Martin"

  • al momento t1 un aggiornamento è fatto per il racconto DB: "User con il nome ID 1 di è Cedric Martin" (cambiando la 'k' a una 'c').

  • una query chiede ancora una volta "qual è il nome dell'utente con ID 1" ora restituisce "Cedric Martin"

E 'un esempio stupido, ma è perché mi piacerebbe capire qualcosa di fondamentale su CouchDB.

Visto che l'aggiornamento è stato effettuato utilizzando un'app alla fine del DB, è possibile interrogare il DB "come era al tempo t0", senza fare nulla di speciale?

Posso chiedere a CouchDB "Qual era il nome dell'utente con ID 1 al tempo t0?"?

EDIT la prima risposta è molto interessante e quindi ho una domanda più precisa: finché non sto "compattazione" un CouchDB, posso scrivere query che sono in qualche modo "referenzialmente trasparente" (cioè saranno sempre produrre lo stesso risultato)? Ad esempio, se interrogazione per "documento d alla revisione r", sono sicuro di ottenere sempre la stessa risposta finché non compro il DB?

+0

Forse questo collegamento è utile per te. http://wiki.apache.org/couchdb/HTTP_Document_API#Accessing_Previous_Revisions –

risposta

26

Forse l'errore più comune fatto con CouchDB è credere che fornisca un sistema di controllo delle versioni per i dati. Non è così.

Compaction rimuove tutte le revisioni non più recenti di tutti i documenti e replica solo le ultime revisioni di qualsiasi documento. Se hai bisogno di versioni storiche, devi conservarle nell'ultima revisione utilizzando qualsiasi schema che ti sembra opportuno.

"_rev" è, come noto, un nome sfortunato, ma non è stata suggerita alcuna altra parola che sia più chiara. "_mvcc" e "_mcvv_token" sono stati suggeriti in precedenza. Il problema con entrambi è che qualsiasi descrizione di ciò che sta accadendo là includerà inevitabilmente "le vecchie versioni rimarranno sul disco fino alla compattazione", il che implica ancora che si tratti di un sistema di controllo delle versioni degli utenti.

Per rispondere alla domanda "Posso chiedere a CouchDB" Qual era il nome dell'utente con ID 1 al tempo t0? "?", La risposta breve è "NO". La risposta lunga è "SÌ, ma in seguito non funzionerà", che è solo un altro modo per dire "NO". :)

+0

grazie mille per queste informazioni, è molto interessante! –

1

t0 (t1 ...) è in couchdb chiamato "revisione". Ogni volta che si modifica un documento, il numero di revisione aumenta. Le vecchie revisioni dei documenti vengono archiviate fino a quando non si desidera più avere vecchie revisioni e indicare il database "compatto". Look at "Accesso alle versioni precedenti" in http://wiki.apache.org/couchdb/HTTP_Document_API

+0

+1 ... è * molto * interessante. Ho modificato la mia domanda un po 'di più: in pratica vorrei sapere se le query possono essere rese trasparenti in modo referenziale (quando viene specificata una specifica revisione). –

3

risposta alla seconda domanda: SI.

I dati modificati vengono sempre aggiunti all'albero con un numero di revisione superiore. lo stesso rev non è mai cambiato.

per il vostro Info:

La revisione (1-abcdef) ist costruito in questo modo: 1 = numero di versione (qui: prima versione), secondo è un hash sul documento di contenuti (non sono sicuro, se c'è ancora un po 'di "sale") ... quindi lo stesso contenuto di documentazione produrrà sempre lo stesso numero di revisione (con la stessa impostazione di couchdb) anche su altre macchine, quando sullo stesso livello di modifica (1-, 2-, 3-)

Un altro modo è: se è necessario mantenere le vecchie versioni, è possibile memorizzare i documenti all'interno di un documento più grande:

{ 
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....} 
    } 
] 
} 

allora si può chiedere per le revisioni:

View "byRev":

for (var curRev in doc.versions) { 
    map([doc.doc_id,doc.versions[curRev].v],doc.versions[curRev]); 
} 

chiamata:

/byRev StartKey = [ "5374"] & endkey = [ "5374", {}]

risultato:?

{id: "docHistoryContainer_5374", key = [ 5374,1] value = {... doc_content v1 ....}} {id: "docHistoryContainer_5374", chiave = [5374,2] valore = {... doc_content v2 ....}}

Additionaly ora è possibile scrivere anche una funzione mappa che consente di modificare la data nella chiave, quindi è possibile chiedere le revisioni in un intervallo di date

+0

geez ma questo è assolutamente enorme!Quindi fino a quando non utilizzi la compatta e fintanto che esegui una query nell'intervallo di date "minore o uguale" alla data corrente, ti garantiamo che le tue query sono trasparenti in modo referenziale? (almeno nel concetto di un DB specifico) Questa è una caratteristica fantastica che penso! Ha il potenziale per rendere molto, molto più facile "ricreare lo stato" (ad esempio quando si traccia/debuggin). E semplicemente, beh, è ​​molto più facile ragionare sul programma in generale. Questo mi fa sicuramente ** molto ** interessato a CouchDB:) +1 a entrambe le risposte:) –

+0

scusa ... l'interrogazione della data è solo nella seconda versione ... non puoi scrivere una mappa che cerchi il contenuto della vecchia versione. Puoi solo "chiedere" un documento specifico per le sue revisioni e quindi recuperare il contenuto di questa revisione, ma non interrogare – okurow

4

Come già detto, è tecnicamente possibile e non si dovrebbe contare su di esso. Non si tratta solo di compattazione, ma anche di replica, uno dei maggiori punti di forza di CouchDB. Ma sì, se non si compatta mai e se non si replica, sarà possibile recuperare sempre tutte le versioni precedenti di tutti i documenti. Penso che non funzionerà con le query, tuttavia, non possono funzionare con versioni precedenti.

Fondamentalmente, chiamarlo "rev" era il più grande errore nel progetto di CouchDB, avrebbe dovuto essere chiamato "mvcc_token" o qualcosa del genere - implementa solo MVCC, non è pensato per essere utilizzato per il controllo delle versioni.

Problemi correlati