8

I have an online document which essentially gets stored to the database as XML string.

I'm thinking about a way to implement versioning of the document for the user. So that user can go back to previous versions of the document.

update In my case it's a web application with hundreds of thousands of users. A user can store unlimited amount of documents. The XML for document is stored in MySQL blob field so it's not small. Eventually I need to cap the limits somehow but that is a different topic all together.

Is there a standard way to approach this? Should I store only the differences between versions? What are other things that I need to consider?

7
  • 1
    The interesting question here is: do you have an existing MYSQL DB infrastructore where the data has to be integrated (especially a system scaled to that many users)? The RCS suggestion of Crazy Eddie does not seem easily to be integrated in such a system.
    – Doc Brown
    Commented May 25, 2012 at 13:53
  • What is the security model -- I assume each users' documents are private?
    – Michael
    Commented May 25, 2012 at 13:59
  • @Michael Yes each users documents are private Commented May 25, 2012 at 16:19
  • @DocBrown Yes I have an existing Mysql db table where these xml documents are stored right now. Commented May 25, 2012 at 16:23
  • @dev.e.loper: I guess the privacy is is not enforced by the DB server, right? The number of users you mention indicates you are talking about a scaled web server solution. The question in place here is: do you want/must have to keep the XML data in the database, or are you free to pick up a different technology for that part of the data?
    – Doc Brown
    Commented May 25, 2012 at 17:24

5 Answers 5

13

Why not use a source control repository? It will take less storage space, does everything you currently want, and would easily let you extend the concept further into branches, tags, etc...all the stuff you get from an RCS. Why reinvent the wheel?

4
  • How exactly do you mean? Are you saying install SVN on my sever and use api to store those files? Commented May 24, 2012 at 19:46
  • Is there a bottle neck somewhere in this approach? For example if I have 50,000 users saving/versioning their work. Source control repository needs to handle versioning for those 50,000 correct? Commented May 24, 2012 at 20:07
  • The OP is talking of a database (I guess, an existing one). I don't know any source control system which easily integrates into an existing database schema.
    – Doc Brown
    Commented May 24, 2012 at 20:40
  • @dev.e.loper - a decent RCS, SVN included, should be able to handle that many users. Commented May 24, 2012 at 22:01
5

Since you're doing this in a database, the easiest way to version your XML string would be to create a new History table with the following columns:

  • History ID
  • New XML string (optional column)
  • Old XML string
  • Insert timestamp

Insert a row to this History table before you update the row on the XML string table.

6
  • If you update the row in the XML string table there isn't any way to get the previous version out. All you can do is see a history of change dates. You'd need to do inserts rather than updates...preferably of diffs. Commented May 24, 2012 at 16:17
  • @CrazyEddie: The previous version (old version) is in the History table. Diffs aren't necessary for one document. Commented May 24, 2012 at 16:23
  • "Diffs aren't necessary" - you don't know how big the document is, how often it gets changed, and if the OP perhaps did not mean "one document per user". So "no diffs needed" is just a wild guess. Nethertheless I gave you +1, since I think your answer points to the right direction. But you can improve it by explaining better what those columns "new version" and "old version" shall contain (XML strings, reference to previous history IDs, or something else?)
    – Doc Brown
    Commented May 24, 2012 at 20:39
  • @Doc Brown: And you don't know how often the old version of the XML string is required, not to mention the time and effort to write a diff engine, which also has to undiff. You don't even know if the database does compression of text strings. I fixed the column references. Commented May 25, 2012 at 13:01
  • @GilbertLeBlanc: We both did not know that (when the OP wrote his first version of the question) - and because of that I would not have written "diffs are necessary" or "diffs aren't necessary" here. I would only suggest not to start with a more complicated diff solution if a simpler non-diff solution may be be enough. I guess that is what you meant.
    – Doc Brown
    Commented May 25, 2012 at 13:43
3

Is there a standard way to approach this?

For a standards-based approach, take a look at the Delta-V extension to WebDAV (itself a widely supported extension to HTTP). Delta-V adds versioning to WebDAV and is described in RFC 3253.

1

A relatively simple way is to increment a revision id upon each save, and save the new xml document under that new revision id.

table: docs

doc_id | name          | current_revision
   1   | Shopping List |       5         

table: doc_revisions

doc_id | revision | timestamp | xml_blob
  1    |    1     | 2012...   |
  1    |    2     | 2012...   |
  1    |    3     | 2012...   |
  1    |    4     | 2012...   |
  1    |    5     | 2012...   |

You might also consider storing the xml files separately in the file system. You can alter the doc_revisions table with a URL/path to the file rather than a blob. That will allow your db to handle far higher volumes on a single server because the database wont physically be as big (you could move the docs to a different server) and you'd be taking the document retrieval load off the db server.

Personally, I wouldnt store the file differences. Rather, I'd store the full new revision of the file each time. Storage is cheap, and no need to complicate things. 'diff' functionality could be inplemented later if eventually turned out you really need it. If you store diffs, be aware it could introduce a bunch of unexpected complexities, for example if you need to search the text of the documents.

1
1

Why not mimic a database log?

Basically, changes are marked chronologically as transactions. For a document DB a transaction would consist of a diffs blob + timestamp instead of an table row entry but the concept works the same. Pretty much the same way version control systems work.

To keep things snappy keep a cached copy of the current version. If somebody needs to go back in time, they can rollback (ie reverse) the transactions until they reach the historical requested they need. The idea being that the cached copy doesn't change until a save operation is performed.

To maintain consistency, you also need to take into account rollbacks. Following what I described already, lets say the user goes back 5 versions. 5 transactions would be reverse-applied in reverse-chronological order to the current version but when that state gets saved, the transaction is stored as a diff from that state compared to the current version.

Basically, history never gets re-written, just re-used to create new versions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.