I don't really have a good title for this post, so I just thought I'd title it with one of my favourite Pink Floyd songs.
A few years ago, the author of Rails somewhat famously
opined thus:
Active Record is opinionated software, just like the rest of Rails. This is a matter of opinion, not constraints. And the opinion goes as follows: I don't want my database to be clever! Keep those crayons firmly in place, please.
Unlike Christopher, I consider stored procedures and constraints vile and reckless destroyers of coherence. No, Mr. Database, you can not have my business logic. Your procedural ambitions will bear no fruit and you'll have to pry that logic from my dead, cold object-oriented hands.
I was reminded for the umpteenth time yesterday just how really, really silly this is. The only part of it that is spot on is the first clause, and I suspect that's because he didn't know that the actual meaning of the word
opinionated is "unduly adhering to one's own opinion or to preconceived notions". Calling someone opinionated is not a compliment - it's an insult.
Here's what happened. Like a great many times before, a client sent me some stuff that was running very slowly and asked me how to speed it up. It was a piece of client side code that made some calls to the database to retrieve data and perform some checks on it and report on those by stashing the exception cases in a table to be later reviewed by the Data Quality team. It's a classic piece of business logic, and according to the dictum above does not belong inside the database. I rewrote it as a PL/pgSQL stored procedure. I didn't change the logic in any significant way. I simple stopped all that data being shipped out to a client to perform checks on it. The result was a reduction in execution time from the client's reported 6 minutes to 3 seconds.
This repeats a pattern I have seen hundreds or thousands of times. So here's my alternative dictum:
Let the database be good at what it's good at, including smart processing of bulk data. If you're lucky enough to be using PostgreSQL, you can implement the business logic in your favourite OO language (e.g. Ruby). Avoid shipping data to an external client program just to process and ship stuff back to the database. Only fetch data from the database if you need it to display or send to another system.
Or keep doing what you're doing, so people will continue to pay people like me to fix it