Decisões de banco têm vida útil de anos. Vale articular cada trade-off
antes que a escolha vire dívida estrutural.
Postgres ou MongoDB para a maioria dos sistemas novos?
Postgres, em quase todos os casos. JSONB cobre o caso "preciso de
campos flexíveis" sem abrir mão de transações fortes, joins,
constraints e EXPLAIN. MongoDB venceria em workloads
massivamente write-heavy de documentos sem relacionamento — um
cenário muito mais raro do que o hype sugere. Quem começa em SQL e
descobre que precisa de NoSQL aprende com base em evidência. Quem
começa em NoSQL e descobre que precisa de joins paga o preço da
migração.
Normalizar até a 3FN ou desnormalizar de início?
Modele em 3FN como default. Desnormalize só quando uma query
específica, medida, mostrar gargalo claro — e quando a duplicação
tiver estratégia explícita de manutenção (triggers, eventos,
views materializadas). "Desnormalizar para performance" sem
medição é desculpa para esquema bagunçado. A 3FN raramente é o
gargalo real; índice ausente, sim.
Read committed ou repeatable read como default?
Postgres usa read committed; MySQL InnoDB usa repeatable read. As
duas escolhas são razoáveis. Entender qual sua ferramenta usa,
e quando subir para serializable em transação específica, importa
mais do que mudar o default. Para lógica de negócio que depende
de ler-modificar-escrever, prefira SELECT FOR UPDATE
ou serializable explicitamente — e teste sob concorrência.
ORM em todo lugar ou SQL puro nas queries críticas?
Mistura. ORM acelera CRUD trivial e preserva tipagem entre código
e schema. Para queries críticas — relatórios, agregações, joins
grandes — escreva SQL e teste com EXPLAIN. ORM tentando
gerar SQL otimizado para casos complexos costuma produzir queries
piores que o SQL escrito à mão por alguém que entende do banco.
sqlc e Dapper fazem essa divisão limpa; EF Core e SQLAlchemy
permitem queries cruas quando preciso.
Quando começar a pensar em sharding?
Tarde. Quase sempre depois de réplicas de leitura, partitioning
lógico no mesmo nó e tuning de queries. Sharding adiciona
complexidade enorme: chaves de shard cruzadas, rebalanceamento,
transações distribuídas. Postgres num servidor decente aguenta
terabytes e dezenas de milhares de TPS. Antes de shardar, esgote
verticalização, índices, cache e read replicas — costumam resolver.