It's not uncommon however in large organisations with mature applications, without strict IT policies.
Complex applications that are undergoing active changes shouldn't be constrained in this manner, and in that context a SQL migration is more of an in-place upgrade of the data structures that hold the application data between different versions of the application.
Adding columns, adding tables, replacing columns with other columns and managing how the data should look in the new schema, based on the 'old' data structures.
These are solved problems, have been for decades.
Business logic doesn't belong in a database. data does.
Or you can rewrite all the third-party apps your organisation uses now and in the future to use your own.
Both solutions are unpalatable: "the database is the integration point we can't ever change" is bad and "no apps have a central ground truth database" is also painful.
I'd prefer the latter with small APIs and more duplication, than the common enterprise solution with a massive holy unchangable db directly serving apps.
In the end it means you give the data an elevated role in the system, and you write the code around the data. When the code would be cheaper to write or maintain with a different data representation - you can't. It's a comfortable situation for a while, but when you eventually grow out of the current system it's a world of hurt.
Like I said - it's two bad (non) solutions but I very much prefer duplication, isolation, inconsistency, a forest of small obscure APIs etc. where I can add/remove/normalize/denormalize/add caching etc - to "the data is the ground truth and the schema we can only change through addition" non-solution.
That's how things are meant to be. The structure of a program naturally follows that of the data it manipulates.
> When the code would be cheaper to write or maintain with a different data representation - you can't.
Who says that? The real problem is that most programming languages aren't capable of integrating database schemas into the type-checking process, so when you change a schema, it's difficult to make sure applications follow through in a consistent manner. That's what makes change unnecessarily risky and painful. But it's possible to do better than that: http://impredicative.com/ur/
Application logic can undergo active changes and refactoring without changes to the data permanent storage, indeed, a 1-to-1 correspondence between DB and application data structures isn't expected. It's just as with backwards compatibility with file formats, changing the application version shouldn't require incompatible in-place changes to the backing data persistence layer - you can need to add some new features, but the old version of the app should work fine with the updated DB.
Transforming data to conform to a new schema. It's a tedious process that could use some automation, but ditching schemas because data migrations are tedious is like ignoring traffic rules because you're in a hurry.
> I assume it's just a bogeyman made up by the MongoDB snake-oil salesmen.
It's just like dynamic type marketing: “If you never define the structure of your data, you never need to worry about it!” The only problem is that it isn't true.