Problema
Tabelas “genéricas” demais, ausência de constraints e agregações que não param de crescer. O sistema escala verticalmente até não escalar mais e ninguém sabe onde cortar.
Solução
Modelar para casos de uso de leitura/escrita dominantes, mantendo invariantes no banco (FK, CHECK, UNIQUE). Planejar hot paths e onde aceitar eventual consistency. Documentar tamanho esperado de agregados e política de arquivo/partição.
Arquitetura
- Entidades core com relacionamentos explícitos.
- Eventos para integrações quando estado derivado pode atrasar ms/s.
- Anti-patterns nomeados: EAV sem necessidade, JSONB como “tudo cabe” sem índice.
Código
CREATE TABLE orders (
id uuid PRIMARY KEY,
customer_id uuid NOT NULL REFERENCES customers(id),
status text NOT NULL CHECK (status IN ('draft','paid','canceled')),
created_at timestamptz NOT NULL DEFAULT now()
);
CREATE INDEX idx_orders_customer_created ON orders (customer_id, created_at DESC);Performance
Evitar SELECT * em dashboards; projeções materializadas quando relatório for pesado; paginação por chave em feeds grandes.
Melhorias futuras
Sharding só com métricas; read models dedicados; data contracts entre times.
Conclusão
Modelagem é decisão de custo operacional para os próximos anos. Escrever sobre trade-offs mostra visão de arquiteto, não só de CRUD.