That ain’t going to take you anywhere
As part of our usual work routine, we field customer questions and inquiries. A pretty common one is to take a look at their system to make sure that they are making a good use of RavenDB.
Usually, this involves going over the code with the team, and making some specific recommendations. Merge those indexes, re-model this bit to allow for this widget to operate more cleanly, etc.
Recently we had such a review in which what I ended up saying is: “Buy a bigger server, hope this work, and rewrite this from scratch as fast as possible”.
The really annoying thing is that someone who was quite talented has obviously spent a lot of time doing a lot of really complex things to end up where they are now. It strongly reminded me of this image:
At this point, you can have the best horse in the world, but the only thing that will happen if it runs is that you are going to be messed up.
What was so bad? Well, to start with, the application was designed to work with a dynamic data model. That is probably also why RavenDB was selected, since that is a great choice for dynamic data.
Then the designers sat down and created the following system of classes:
public class Table { public Guid TableId {get;set;} public List<FieldInformation> Fields {get;set;} public List<Reference> References {get;set;} public List<Constraint> Constraints {get;set;} } public class FieldInformation { public Guid FieldId {get;set;} public string Name {get;set;} public string Type {get;set;} public bool Required {get;set;} } public class Reference { public Guid ReferenceId {get;set;} public string Field {get;set;} public Guid ReferencedTableId {get;set;} } public class Instance { public Guid InstanceId {get;set;} public Guid TableId {get;set;} public List<Guid> References {get;set;} public List<FieldValue> Values {get;set;} } public class FieldValue { public Guid FieldId {get;set;} public string Value {get;set;} }
I’ll let you draw your own conclusions about how the documents looked like, or just how many calls you needed to load a single entity instance.
For that matter, it wasn’t possible to query such a system directly, obviously, so they created a set of multi-map/reduce indexes that took this data and translated that into something resembling a real entity, then queried that.
But the number of documents, indexes and the sheer travesty going on meant that actually:
- Saving something to RavenDB took a long time.
- Querying was really complex.
- The number of indexes was high
- Just figuring out what is going on in the system was nigh impossible without a map, a guide and a lot of good luck.
Just to cap things off, this is a .NET project, and in order to connect to RavenDB they used direct REST calls using HttpClient. Blithely ignoring all the man-decades that were spent in creating a good client side experience and integration. For example, they made no use of Etags or Not-Modified-Since, so a lot of the things that RavenDB can do (even under such… hardship) to make things better weren’t supported, because the client code won’t cooperate.
I don’t generally say things like “throw this all away”, but there is no mid or long term approach that could possibly work here.
Comments
Ouch, it kinda looks like they are still thinking in relational terms, which I did when I first picked up RavenDB. It wasn't until I had you do that screen cast with me on doing the Multi Map Reduce that things started to sink in and I could step away from the whole relational thing.
And not using the sexy LINQ api? :(
Wow. Never seen such a mess at the architecture level.
Those tables are usually the added work you have to do if you want a dynamic system with relational databases.
This is why you need an architect that knows his stuff BEFORE making critical decisions.
The desgin was bad enough in itself, but as I read that they used REST calls I quickly glanced at the calendar if it was april fools already.
I follow the development of RavenDB with interest, but I've not used document databases for anything more than toy projects.
I know how to design for relational databases - but have no idea how to design for document databases. I know the above example is wrong, but I wouldn't be able to say what's right.
Is there a particular book/video/course that anyone would recommend on the subject of designing for such databases?
Rik, there are several books about RavenDB. The one I'm writing is here: https://github.com/ayende/book/releases
@Rik Hemsley I don't know what book to recommend, but I would start with Eric Evans book, Domain Driven Design.
I also tried to blog a bit about it too.
http://www.philliphaydon.com/2012/07/ravendb-what-am-i-persisting-what-am-i-querying/
When people start to abstract too much, I tend tgo make the joke "Hey, let's add a Table called Table, a table called Column and a thrid one called Field."
I would never have thought that someone would take this joke seriously.
I've seen many bad practice designs in my career, but such as this one is really a new record
I just reviewed a project and it contains the exact same design... I recommended to throw it away and redesign it. The best part is that other guys in the team (did not write the code) think it is a OK design and we should keep it.
In a document database the Table class should be named Document ;) (Fixed)
I have seen legacy systems like that which tried to avoid limitations of relational databases. But why would anyone do that in a document database?
It looks like they were trying to reinvent the relational database... Also. .. this seemed relevant http://devopsreactions.tumblr.com/post/112213552683
As someone who has never ridden nor cared for a horse before, I have to ask: what's the meaning of the photo? My assumption is something is terribly wrong here, but then again maybe the caretaker is just giving the beast a massage :)
Eli, It is a pretty stupid thing to do to a horse, and you can't ride it anywhere, that is the point
Comment preview