- Pick what you know
- Pick what's boring (i.e. settled technology)
- Pick what others know and understand
- Don't be afraid to change schemata or DBs - in fact, get comfortable with the idea from the beginning. This prevents mental lock-in
- You don't need a specialized database (i.e. graph, time-series). If you need one, you already know it.
- Always, always have backups and test them.
And some more subjective takes:
- Sharding is easier than distributed DBs. If you can design your data flow to be largely unidirectional and compartmentalized (i.e. user profiles etc.), you benefit massively
- Multi-Master replication is often a huge cost in terms of complexity and risk. Avoid it wherever you can. If you can't, get someone who has battle scars to help you.
You can always refactor if the project is a huge success and could benefit from a more obscure db.
1. Portability - Ensure that the database in use can be installed on a developer workstation or off-cloud in an on-prem production environment. Amazon's DynamoDB looks amazing and it's a shame I'll never use it.
2. Compatibility - If you can't get 100% portability then at least ensure the protocol is identical to something you could use elsewhere. This is why I compromised on using Amazon Aurora for example, because it's protocol compatible with MySQL.
3. Maintenance - if you pick a relatively new database technology then you will need to run your own servers. You will need to figure out backups and test them. If you use something boring like MySQL or Postgres, you can just host this in a managed service with everything you need to use it in production. You pay more, but you spend less time, which is the only thing you cannot borrow or buy.
But your point about on-prem stands
I am tempted to use DynamoDB from time to time but I've won a few jobs with our ability to deploy to a customer environment, even if they don't always end up doing that. Most of our competitors won't even entertain the idea, so it's a great box to be able to tick.
Note: My experience is in B2B. This isn't such a concern for B2C at least not today. Nonetheless, I would still not want to tie myself to AWS too tightly for a B2C app. Amazon is great today. Tomorrow, who knows? After all, I remember the days when nobody got fired for choosing IBM. I'm not so sure that's true now.
It was designed to power experiences that look like shopping carts: relatively short-lived, mostly append-only, needing a flattish performance curve as the number of items and users go up, with a really natural partition key.
Using it as the primary storage of your app means you play the part of query planner a lot of the time.
If your data is especially graph-structured you might end up doing so-called "single table design" where all objects end up in the same table that has its keys constructed carefully (compound keys formed by string concatting), And has secondary sparse indices to power other access patterns.
And definitely plan on overfetching as an _optimization_ to prevent many small queries to dynamo, especially in a GraphQL context where we have no idea what fields are being requested at fetch time.
Bit outdated ckmparison but might help
Theres also timescaledb, clickhouse, etc etc
Thanks for the shout-out for TimescaleDB (I'm the community manager for Timescale...)
Otherwise, use Postgres or MySQL depending on what your team prefers or has experience with.
Done.