Skip to content

Instantly share code, notes, and snippets.

@kellabyte
Last active December 12, 2015 07:59
Show Gist options
  • Save kellabyte/4741078 to your computer and use it in GitHub Desktop.
Save kellabyte/4741078 to your computer and use it in GitHub Desktop.
// Struct Store
//
// Version 1: We may have written...
DocumentDatabase db = new DocumentDatabase();
User user = new User();
user.Id = 123;
user.FirstName = ....;
user.LastName = ....;
user.Bio = ....;
db.Put(user);
// Version 2: Two years forward... I want to add a Twitter handle.
DocumentDatabase db = new DocumentDatabase();
User user = db.Get(123);
user.TwitterHandle = ...;
db.Put(user);
// But because I have 100 servers, I can't afford to take all 100 down at once to make
// this change. So I'm going to do what any highly available service does,
// run parallel versions.
// Scenario: The cluster is going through a week long rolling upgrade that will eventually
// upgrade the entire cluster.
//
// 1. User adds their twitter handle to their profile.
// 2. Version 2 of the service stores new User struct/class to document DB with the twitter handle.
// 3. User 4 days later decides to update their bio.
// 4. Version 1 of the service handles the request, modifies the User document.
//
// Because version 1 and 2 use class/struct serialization, #4 above lost the twitter handle. Gone.
//
// We took flexible document databases using an extensible data formats (XML/JSON) & ejected flexibility.
//
// This is what happens when we treat databases as extensions of our programming language.
// We lose the benefits of the data model the database provides because we tried to
// type everything to death.
//
// This is just one example of Stuct Store, not Document Database.
@kellabyte
Copy link
Author

Lotus Notes, the document database (yes!) only persisted and synchronized modified deltas of documents. Today's document databases don't really have a concept of a document.

Today's document databases typically store or retrieve entire values from a key/value store.

@peteraritchie
Copy link

Honestly, to push that level of knowledge into the code that calls Get/Put is a responsibility violation. The code that uses a User object shouldn't have to care about anything it doesn't need to know about. See (SRP and Interface Segregation). The "database" class (or a Repository wrapping it) should deal with that responsibility--it can be smart enough to know that despite having a UserV1 object that there's a bunch of other data that UserV1 doesn't contain but is in the database and assume a "Put" is an upsert.

@kellabyte
Copy link
Author

@peteraritchie that's going to introduce some pretty complicated code (change tracking) to figure that out. A lot of complexity I would argue isn't required if we weren't trying to be so addicted to strict typing. A domain can be loosely typed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment