For context, I've previous experience with NHibernate, EF, EF Core, Dapper and some others from yesteryear - Marten is probably the best dev experience I've had from an ORM.
> What would an RDBMS have brought us?
It would probably work using a forms table, fields table, submissions table, and values table.
It would probably work using a forms table, fields table, submissions table, and values table.
I didn’t ask “would it have worked”, I asked “what would have bought us”.
Maybe I don’t follow. You would insert a row into the fields table. Millions of rows should be fine.
> I asked “what would have bought us”.
I don’t know. None of this matters really, as long as the service works.
On any good RDBMS, adding a nullable column to an existing table is an O(1) operation. This is the only option that's comparable to what's available in MongoDB, and it has the same performance characteristics.
On the great ones, adding a non-nullable column with a default value to an existing table is also an O(1) operation. The good-but-not-great ones, it's also O(N). (As always, you get what you pay for.) For MongoDB, wanting to do this would be unusual, but you would have the option of back-filling every record. It would be an O(N) operation, too. So, for this case, the characteristics of the RDBMS are no worse, and possibly better.
Adding a non-nullable column with no default is always O(N), but the fact that you're suggesting a document store as an alternative implies even more strongly that this is not the use case you're trying to cover. That said, if you did do it, it would also be O(N).
Converting a numeric column to a string column is always going to be O(N), yes. Whether or not that's the better option is something that's got to be decided in context. Basically, do you want to pay the cost of datatype conversion in one lump sum and then be done with it forevermore, or do you want to pay a small fee for datatype coalescing every time you access that field? There are good reasons to choose both options. However, all too often, the 2nd option is chosen for a very bad reason: Simply assuming that it's zero cost.
This would fit in a single SQL query which is expected to perform reasonably well, with an unstructured database optimizing this query will take months of work.
db.formEvent.aggregate([
{ $match: { createdAt: {$gte: ISODate("whenever")}}},
{ $group: { _id: "$custId", userAgents: { $addToSet: "$metadata.userAgent" } } },
{ $sort: { createdAt: -1 } }
])
Something like this? I'm not sure why this couldn't be an optimized query in mongo, but I'm also not sure why a query like this one needs to be optimized? This would run fast enough without needing indexes, and really fast with an index on a couple fields, but is a query like this run so frequently you need to have it be extremely optimized?If you can know for sure from the start that you'll never need queries like this, then of course something like Mongo will be awesome. But requirements change, hence this article.
At another company where I worked where we used Postgres, we had a multitenant set up where each of our (large) customers had their own database. The issue would have been the same.
You would no more “scan over all of your data” with Mongo with indexed fields than you would with an RDMS with indexes.
As requirements change, you do need to migrate your data into a schema that makes sense and that's regardless of whether you're using SQL or MongoDB.
In fact, if you are using C#. You could use the same LINQ syntax either way.
But people don’t seem to understand that there are plenty of scenarios where you really either don’t know the schemes in advance and/or the “schema” is defined by an external source.
I worked for a company that sold software that allowed users to create forms that could be filled out either on the web or via a mobile app.
The user created the form and the schema and the indexes were created on the fly - one collection per type of form. What would an RDMS have bought us?