People are so spoiled this days. What is so hard in writing table migration, it is like a few minutes of your time. And why would some non techy product manager even know that you wrote some migration sql file. It is a minuscule technical detail related to the chosen technology and he will not see any repercussion in the production. But try to explain to him why after some reckless sprints you got many inconsistencies in the user facing app which you will have if you abuse "schemaless" NoSQL but use implicit schemas which change over time without proper checks. And if my product manager will push just for initial speed all the time without 0 time for some basic architecture (and I mean really basic), engineering practices and such, you know really useful stuff, I would leave that place without second thought. It is digging it`s own hole from the beginning.
And what is the problem of data migrations? Implicit schemas in MongoDB are much worse of a problem when your data requirements change. With relational databases you at least have integrity checks on the DB level that guard you from much of the possible problems when doing such migrations.
Wow, I wrote migration script for a couple of table rationalisation and it took me a week, to make it error-prone and to provide a revert option. Not to mention that you usually need to work with production data on your local to test if the migration will work without any errors.
And If you happen to have a migration error on your production database. It is a terrible experience, which usually includes downtime.
Maybe my lack of experience on writing SQL migrations increased that time, but isn't this the whole point of the OP in terms of dev first.
Even when you use a schemaless db like MongoDB, you still have to manage your data (let's say the schema is implicit).
If for example you decide that the "phone number" field is no longer a string but a list of objects (containing each the phone number and the kind of number), you will have to update the old data to adapt it to the new model, incurring in the risk of messing up production data.
Of course you can (and it is what many people do) avoid the problem at the data level and "fix it" at the application level (for example, checking every time if you have a single string or the new list), but if you really want you can do the same with a SQL database (keep the "phone" field on the table, but add the new table for the list of numbers).
A disadvantage of the SQL approach is that many are less versed in it than in the application language, but there are many tools available to handle SQL migrations in your framework's language.
Yes, the "secret" to MongoDB not having to write data migrations is simple: you get to simply have them as technical debt for later.
What could go wrong ?
Well, that's easy too: an accounting system where each method has a switch with 10+ cases, each case having 30+ lines of code inside of it, depending on something like "record version" or worse, on implicit tests.
And what could be worse ? Well, having a switch with only 9 cases in one of those methods ...
This is essentially how my team handles things while using HBase as our main DB. At first it felt weird to not write a migration at the DB level and maintaining compatibility is certainly something that you have to keep in mind at all times, but we have a pretty solid internal library for handling de/serialization in Scala.
> A disadvantage of the SQL approach is that many are less versed in it than in the application language, but there are many tools available to handle SQL migrations in your framework's language.
I was surprised by this at my previous job. One of the first things I learned about when starting to do web development was database migrations (Miguel Grinberg's Flask tutorial). Sure, I had to learn Alembic when I started the job, but it's a pretty straight forward API and the main issue was the lack of transactional DDL in MySQL that we constantly had to keep in mind. Besides that it was just writing SQL statements wrapped in Python.
What about removing a column? What about if you've decided that you both current and next version of the code to work (then removing a column is a 3 step process, copy to new and use new, skip a version, remove old).
Migration can and is often hard.
Either you kick the can to the code, or do a migration script. Is there some magic style of coding that allows me to use the old data structures with the new code without having to do any special checks?
Well, there's your problem right there!
...if you're making a relatively small change to a non-mission-critical, non-distributed system that can be taken offline briefly while you migrate; then you can just shut everything down, migrate, roll new versions, and start up again.
If you need to keep everything running while you do a gradual rollout across thousands of DBs, this gets more complicated very quickly - and that's not even taking into account more complex migrations that involve more than just "add / remove this column".
You're definitely right, however, to point out that implicit schemas don't make this better: you have all the same problems, but with less documentation / validation helping you not screw things up. It's also a good point that many businesses / applications never reach this latter stage where migrations become much, much more complex; when you can get away with the former approach, you definitely should.
I have worked on a number of large enterprise projects where there were hundreds and hundreds of migrations over the lifespan. I have never seen it take minutes of time. Or maybe you're just one of those fun developers who never properly tested their work.
But I have definitely seen production outages and subsequent failures to rollback because of edge cases between various individual migrations.
And I have written many migrations in systems with tens of different db`s/schemas in the same project which could be different based on the geographical region or some other requirement and never had any big problem
Especially since you need to write the rollback script as well. And then test it with data. And then ensure there are no weird interactions with other migrations. Because if there is a problem with any one of them then it can be a huge headache to unwind everything.
But often you are adding to reference data or running a transform SQL in order to produce some new denormalised table or the huge array of changes needed to support new use cases. These can't be automated and are hugely error prone.
Unless you migration involves "disable all checks, add new columns/tables, move and delete old data, enable all checks"
If you are migrating to a denormalised table then it should obviously crash when your conversion tool is doing something wrong and the RDBMS just prevented it from succeeding in doing something wrong.
If your migration is actually error prone as in "mangling and corrupting" data I suggest you are doing something wrong and you probably disabled the safety checks in your RDBMS.
The company I work for has 10's of TB's of data on most customer systems, and migration is either impossible as they have no place to store it, or too costly in time to move.
So while writing the code is not hard, the difficulty (or even possibility) of field upgrades can vastly influence whether or not a feature is considered.
That's absolutely true, but this is also what gave it a bad rep. It put security on the back-seat, and since it's "convenient" and just REST, it allows for moronic stuff like talking to your database straight from a client's web-browser. Security as an afterthought promotes bad or inexperienced developers to do silly stuff, and since MongoDB focuses primarily on web applications - that is a really really bad thing. How many leaks have there been simply because the database was exposed to the public internet without any authentication? Too many.
Now the problem is that inexperienced devs will flock to something that makes it that easy, and there's no real way of preventing that, but developers should never be put first - it leads to lazy solutions and compromises on too many other levels.
Yes, I like it. And you know what? My databases have lots of checks in the schema. This way I know, that I get correct data when I query the database. In MongoDB I'm not sure. I can throw there anything, and get anything. It's just a normal GIGO queue.
And the migrations are fine. You just need to know the tools. I observed huge programmers' aversion to learn SQL (however they don't complain when they need to learn HQL).
I have never worked with a company that was sunk by the cost of migrating data between schemas. I have, however, worked with companies where the bugs that come with a schemaless database have almost sunk it. YMMV of course but I think it’s a false trade-off.
I would say that the developer experience was good in the sense that it was very easy to replicate Mongo databases - but that’s more of a system administration thing. I honestly don’t think that schemaless databases add any real value.
Mongo has its place, but its place isn't in most line-of-business applications for SMEs.
"Pick the right tool for the job" has been the biggest casualty in the midst of the schemaless hype we're going through right now.
Even getting to the point of realizing that most domains where NoSQL or schemaless solutions thrive are also domains where you need to be thinking in suites of persistence technology, ie where trying to choose a single data persistence technology is crazy, would be a big step.
A beast like Reddit (for example), has clear areas where a document centered schemaless approach would yield big wins, but that doesn't mean it's ideal for handling their advertising billing or their master data.
"The job" is quite often many smaller jobs, each of which needs it's own tool. Sometimes it's a lot easier to put on slippers than to carpet the whole world.
Here's the thing, in practice relational databases aren't hard, nor will most devs ever need to know what relational theory is in order to be productive with databases built on it. Performance optimization does get a bit harder but there are relatively few situations where there's any magic involved, knowing how to read an explain plan and when/where to add an index is what most of it boils down to.
data integrity isn't good enough for a product manager? It's like saying "statically typed languages aren't worth the effort, do everything in JavaScript".
Furthermore, MongoDB or not, an application in development needs DB migrations. I don't believe one second you can change all your classes or structs and pretend like MongoDB will magically update your previous documents and collections to the current state of your application.
But one huge advantage of MongoDB is that it is schemaless. And so you have a lot more options for how you migrate documents. For example you can move all of the data under a particular key e.g. "v1" and allow two schemas to co-exist within the one document. Significantly less risky than running migration scripts or doing a alter schema in production.
What schemaless lets you do is hide your risk better by disguising those steps. "db.table.update({$set: ...}, {multi: true})" looks friendly, but it's the same terrifying operation as running DROP TABLE A the instant you're done generating table B. And it looks easier, but that's because your code's beliefs about which schema it's reading from are hidden and implicit.
Painters sounds about right.
Whatever the inconvenience is, I need to be able to stand in for them being an acceptable price to pay for my personal convenience. And that is much more likely to be the case if I carry the "inconvenience" part of the equation, while others get the "convenience" part - like the operations people, or the end user, or other developers. That's because I consider myself a professional who's getting paid good money to make other people's life easier, especially if those "other people" vastly outnumber myself or the few other devs on my project team. That is the essence of my job, and it's not intended to be "convenient" for me - developer convenience is therefore one of the least-relevant criteria by which I ought to choose how I'm going to do it.
Developers who highly value "convenient" solutions are bloody amateurs in my book, especially if they can't even envision the ways in which their convenience has to be paid for by others.
Specifically, I would say mobile and node.js developers. The other part that worked well was so sharding, out-of-the-box. Oh, there were major issues like an index updates skipping documents, but it appeared to work and was the easiest to set up.
Most database systems came from relation theory background and optimize for performance, operations, data safety, but often developer convenience was sacrificed.
Did anybody liked writing data migration? Try explaining value of table migration to some Product Manager of early startup :-).
You can argue if that's were the right tradeoffs, but that's how MongoDB get a lot of steam.