Search code examples
versioningcouchdbdatabase-versioningdocument-storage

CouchDB versioning strategy


Would the following be a viable strategy for implementing versioning(using "example" as a sample document type):

Have one original document where the type field is named example_original.

Subsequent changes to the document all have type example_change and the id of example_original document as a key. The change would also carry a timestamp.

Keep one doc with type example_current that is the result of example_original with all example_change "applied". A new example_change document would automatically be applied to this document.

Finding a specific version would consist in retrieving the example_original doc and applying the desired changes (mostly up to a certain timestamp, but it could also be a number of changes).

I should mention that my use-case will involve a limited number of changes to the original. Most updates will consist of new original documents. While this is my current use-case I would also be interested in issues that would result if many changes where involved.

What pros and cons do you see in this approach?


Solution

  • My first worry is: When "getting" a certain version, can you apply the changes to the original without modifying the database?

    Will you ever need to delete something from the history? Are you really sure? Really, really sure? How about branches?

    All in all, this looks like a complex strategy. Keep in mind that I've heard about CouchDB but never used it. I'd go for a more simple approach:

    1. When you create a document, you assign a UUID. Don't use the name or you'll run into trouble during rename operations. Add a version field that reads "1". Create a second document which contains a list of documents with the same UUID or add a "parent" pointer to the first document.

      Having a "history document" per document allows for faster navigation of the history but parent pointers are more "safe" (since you can't easily create illegal structures with them).

    2. When you create a new revision, reuse the UUID and assign a new, unique version. Update the history document or the parent pointer.

    This strategy is pretty simple to implement and allows all kinds of flexibility later. You can erase parts of the history easily, rename is simple, and you can create branches.