-
-
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. |
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.
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.
@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.
@jbogard the example usage is fairly spot on with most document dbs. you need to explicitly state you want to update only the fields you're changing. Since we are populating an object based on strict serialization it will automatically drop fields that don't exist when you reserialize the object back to json/whatever.