Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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?

share|improve this question
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 May 25 '12 at 13:53
    
What is the security model -- I assume each users' documents are private? –  Michael May 25 '12 at 13:59
    
@Michael Yes each users documents are private –  dev.e.loper May 25 '12 at 16:19
    
@DocBrown Yes I have an existing Mysql db table where these xml documents are stored right now. –  dev.e.loper May 25 '12 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 May 25 '12 at 17:24

5 Answers 5

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?

share|improve this answer
    
How exactly do you mean? Are you saying install SVN on my sever and use api to store those files? –  dev.e.loper May 24 '12 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? –  dev.e.loper May 24 '12 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 May 24 '12 at 20:40
    
@dev.e.loper - a decent RCS, SVN included, should be able to handle that many users. –  Crazy Eddie May 24 '12 at 22:01

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.

share|improve this answer
    
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. –  Crazy Eddie May 24 '12 at 16:17
    
@CrazyEddie: The previous version (old version) is in the History table. Diffs aren't necessary for one document. –  Gilbert Le Blanc May 24 '12 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 May 24 '12 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. –  Gilbert Le Blanc May 25 '12 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 May 25 '12 at 13:43

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.

share|improve this answer

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.

share|improve this answer
    
As far as storing file differences, I'm looking into storing diffs with help of diff-match-patch library code.google.com/p/google-diff-match-patch –  dev.e.loper Dec 3 '12 at 23:47

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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