MySQL ou PostgreSQL: qual escolher? Comparativo sem torcida
Comparativo prático entre MySQL e PostgreSQL: tipos de dados, concorrência, extensões, replicação e custo operacional. Com exemplos de SQL e recomendação clara por cenário.

Essa é a briga de torcida do nosso mundinho. Tem gente que defende PostgreSQL como time de futebol e gente que jura que MySQL resolve tudo. Eu ganho a vida com os dois, então vou fazer o que ninguém faz na internet: falar bem e mal dos dois.
A diferença de filosofia
MySQL nasceu para ser rápido e simples em cargas web. PostgreSQL nasceu na academia, com obsessão por correção e extensibilidade. Isso explica praticamente todas as diferenças que você vai encontrar depois.
| Critério | MySQL 8.4 | PostgreSQL 17 |
|---|---|---|
| Concorrência | MVCC com undo log no InnoDB | MVCC com versões na própria tabela (exige VACUUM) |
| Tipos de dados | Conjunto enxuto e previsível | Arrays, ranges, tipos customizados, enums reais |
| JSON | JSON binário, bom | JSONB com índice GIN, excelente |
| Extensões | Plugins limitados | PostGIS, pgvector, TimescaleDB, pg_partman |
| Replicação | Assíncrona/semi-síncrona nativa, simples de montar | Streaming e lógica, mais poderosa e mais trabalhosa |
| DDL online | Muito bom no InnoDB | Bom, mas exige cuidado com locks em ALTER |
| Curva de aprendizado | Menor | Maior |
Onde o PostgreSQL ganha fácil
Consultas analíticas complexas, geoespacial (PostGIS não tem concorrente no mundo relacional open source), busca vetorial para IA com pgvector, e qualquer coisa que peça tipos ricos. Veja algo que é natural em Postgres e chato em MySQL:
-- PostgreSQL: array nativo e busca por sobreposição
CREATE TABLE artigos (
id BIGSERIAL PRIMARY KEY,
titulo TEXT NOT NULL,
tags TEXT[] NOT NULL DEFAULT '{}'
);
CREATE INDEX idx_tags ON artigos USING GIN (tags);
SELECT titulo FROM artigos WHERE tags && ARRAY['mysql','performance'];
No MySQL você resolveria com tabela de junção (o jeito certo) ou com JSON e coluna gerada (o jeito prático). Funciona, mas é mais artesanato.
Onde o MySQL ganha e ninguém admite
Simplicidade operacional em OLTP de alta concorrência. Replicação em minutos, ferramental de backup consolidado, ecossistema de hospedagem barato em qualquer canto, e um comportamento muito previsível quando a carga é "muitas transações curtas".
-- MySQL: leitura por chave em carga OLTP, o pão com manteiga
EXPLAIN ANALYZE
SELECT p.id, p.total, c.nome
FROM pedidos p
JOIN clientes c ON c.id = p.cliente_id
WHERE p.cliente_id = 91823
AND p.criado_em >= NOW() - INTERVAL 30 DAY
ORDER BY p.criado_em DESC
LIMIT 50;
Com o índice composto (cliente_id, criado_em) isso responde em microssegundos e escala com hardware modesto. Também não existe VACUUM para esquecer de ajustar — e olha que o número de incidentes causados por autovacuum mal calibrado em Postgres não é pequeno.
O custo escondido: quem opera
PostgreSQL entrega mais poder por linha de SQL, e cobra isso em conhecimento operacional: bloat, wraparound de transaction ID, tuning de autovacuum, connection pooling obrigatório (PgBouncer) porque cada conexão é um processo. MySQL tem threads e aguenta conexões ociosas com mais tranquilidade.
Regra prática que uso em consultoria: se o time não tem alguém com tempo dedicado a operar o banco, o MySQL perdoa mais erros.
Minha recomendação por cenário
- SaaS transacional, e-commerce, API de alto volume: MySQL. Simples, barato, previsível.
- Produto com geodados, busca semântica, séries temporais ou modelagem complexa: PostgreSQL, sem pensar duas vezes.
- Equipe pequena, prazo curto, sem DBA: MySQL gerenciado na cloud.
- Sistema que vai virar plataforma com dados heterogêneos: PostgreSQL, porque as extensões te salvam lá na frente.
- Já está rodando e funcionando: fique onde está. Migração de banco é projeto, não tarefa.
Se a sua dúvida real era outra, dá uma olhada em MySQL ou MariaDB, em MySQL com grandes volumes de dados ou volte ao guia definitivo de MySQL.
Sobre o autor: Alexandre Almeida atua com bancos de dados há mais de 25 anos, foi instrutor oficial de MySQL e Oracle para mais de 1.000 alunos e é autor de Aprendendo MySQL. Quer treinar isso na prática, com máquina virtual pronta? Veja os treinamentos.
Fontes: MySQL 8.4 Reference Manual, PostgreSQL 17 Documentation (MVCC, Routine Vacuuming, Indexes) e experiência em ambientes de produção nos dois bancos.