ADR-0007 Base de dados
Motor de base de dados padrão da empresa — PostgreSQL.
- Decisão
- PostgreSQLGuardar e proteger
- Estado
- Aceite
- Data
- Âmbito
- Predefinição da empresa para todas as novas apps
Ligações
Contexto
Seção intitulada “Contexto”Cada app precisa de um sistema de registo. A decisão de deploy — contentores Docker com Bun na nossa própria infraestrutura (ADR-0003, ADR-0035) — eliminou a maior restrição: ligações TCP diretas e de longa duração com um pool em processo, pelo que toda a gama de bases de dados relacionais está em cima da mesa, sem proxies de pooling nem soluções alternativas para edge runtimes.
Requisitos:
- Núcleo relacional — os nossos domínios são estruturados e interligados
- Consistência forte e integridade transacional por predefinição
- Funciona por TCP direto a partir do runtime da app
- Combina bem com uma camada de queries TypeScript com tipos seguros (ADR-0008)
- Margem para crescer: queries de relatórios, pesquisa de texto integral, blobs JSON, futuras necessidades de IA/vetores
Opções consideradas
Seção intitulada “Opções consideradas”1. PostgreSQL
Seção intitulada “1. PostgreSQL”A escolha predefinida da indústria, por boas razões: a base de dados relacional open-source mais capaz.
Prós
- O conjunto de funcionalidades mais rico: JSONB, pesquisa de texto integral, CTEs, window functions, DDL transacional
- Ecossistema de extensões: PostGIS, pgvector (futuras necessidades de IA/embeddings), pg_trgm
- Todas as ferramentas o suportam primeiro — drivers, ORMs (o Drizzle é Postgres-first), dashboards, ferramentas de migração
- TCP direto a partir do contentor da nossa app — sem proxy, sem camada HTTP
- Corre como contentor irmão na nossa configuração Docker; o Postgres gerido (Neon, RDS, Supabase) é um substituto direto por produto se o esforço de operação alguma vez se tornar relevante
Contras
- A operação fica connosco: backups, atualizações, vacuum/monitorização (verdade para qualquer base de dados autoalojada, mas real)
- Mais pesado do que o SQLite para apps triviais
2. MySQL
Seção intitulada “2. MySQL”O outro SGBD relacional open-source de referência.
Prós
- Maduro, muito difundido, bem compreendido em termos operacionais
- Perfeitamente adequado para cargas de trabalho CRUD normais
Contras
- Conjunto de funcionalidades mais fraco onde interessa: suporte de JSON, historial de CTEs/window functions, DDL transacional
- Ecossistema de extensões mais reduzido; sem equivalente do pgvector com a mesma adoção
- A tutela da Oracle lança sombra sobre a direção a longo prazo
- Sem vantagem compensatória face ao Postgres para a nossa stack
3. SQLite (+ Litestream)
Seção intitulada “3. SQLite (+ Litestream)”Base de dados embebida, replicada para armazenamento de objetos para garantir durabilidade.
Prós
- A operação mais simples possível: um ficheiro, sem servidor, sem ligações para gerir
- Extremamente rápido em apps de nó único com muitas leituras
- O mais barato de manter
Contras
- Escritor único — entra em conflito com a escala horizontal, que o ADR-0003 mantém explicitamente em aberto
- Sem modelo de acesso por rede; todos os servidores de aplicação têm de estar no mesmo local que o ficheiro de dados
- Encaixa pior como predefinição da empresa: ótimo para ferramentas pequenas e específicas, errado como padrão de arranque de todos os produtos
- O Litestream acrescenta um modelo de replicação que a equipa teria de aprender e em que teria de confiar para dados primários
Decisão
Seção intitulada “Decisão”O PostgreSQL é o motor de base de dados padrão da empresa para todas as novas apps.
Topologia predefinida: o Postgres corre como contentor irmão ao lado da app na nossa configuração Docker (ADR-0003), ligado por TCP direto. Um serviço de Postgres gerido é uma substituição aceitável por produto quando reduz claramente o esforço de operação — o padrão do motor não muda.
Os fatores decisivos: o conjunto de funcionalidades mais rico (JSONB, texto integral, extensões como o pgvector para futuro trabalho de IA), suporte de primeira classe em todas as peças da nossa stack, TCP direto a partir do contentor da app e um mercado de contratação que esmagadoramente o conhece. Aceitamos ficar com a operação da base de dados.
Consequências
Seção intitulada “Consequências”Mais fácil:
- Um único motor para aprender a fundo: pooling de ligações, backup/restauro, indexação e otimização de queries passam a ser conhecimento partilhado da equipa
- As necessidades futuras ficam cobertas sem um segundo armazenamento: documentos JSONB, pesquisa de texto integral, embeddings pgvector
- A decisão da camada de queries (ADR-0008) fica com o dialeto mais bem suportado do Drizzle
Mais difícil — o que passamos a assumir:
- Backups, simulacros de restauro e cadência de atualizações por ambiente
- Disciplina na gestão de ligações (dimensionamento do pool) à medida que as apps crescem
- As migrações são um processo nosso — tratadas pelo Drizzle Kit (ADR-0008)
Do que abdicamos: da simplicidade zero-ops do SQLite para ferramentas pequenas. Aceite — um padrão único e capaz vale mais do que uma lotaria de bases de dados por projeto; uma ferramenta genuinamente minúscula pode sempre propor um ADR de exceção.

