Pular para o conteudo principal

Como modelar entidades

Como transformar regra de negócio em entidades, relações e restrições úteis, evitando tanto a fantasia do futuro quanto a pressa do CRUD.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

Trilha

Trilha de system design para entrevistas

Etapa 7 / 19

O problema

Quando alguém começa a modelar dados, costuma cair em um dos dois buracos clássicos.

Buraco 1:

  • cria tabela para qualquer palavra que apareceu na conversa

Buraco 2:

  • enfia tudo em uma tabela só porque “depois a gente separa”

Os dois parecem práticos no começo.

Os dois costumam cobrar caro depois.

No primeiro caso, o schema vira um labirinto de relação que ninguém precisava.

No segundo, tudo fica misturado:

  • regra de negócio
  • dado derivado
  • histórico
  • estado atual
  • informação que muda em ritmos diferentes

Então o problema não é só “como desenhar tabelas”.

É saber o que realmente merece identidade própria no sistema.

Modelo mental

Pense assim:

entidade boa é coisa que o sistema precisa reconhecer, relacionar e proteger ao longo do tempo.

Essa frase ajuda porque nem tudo que existe no negócio precisa virar tabela.

Algumas coisas são entidades claras:

  • usuário
  • pedido
  • pagamento
  • assinatura

Algumas coisas talvez sejam só parte de outra entidade:

  • endereço de entrega
  • valor monetário
  • preferência de notificação

Algumas coisas têm mais cara de evento ou histórico do que de entidade principal:

  • mudança de status
  • tentativa de pagamento
  • reprocessamento

Então uma pergunta melhor do que “isso existe no negócio?” é:

  • isso precisa existir sozinho?
  • isso tem regra própria?
  • isso muda separado do resto?
  • isso será consultado ou atualizado isoladamente?
  • isso precisa de identidade própria?

Se várias respostas forem “não”, talvez não seja uma tabela nova.

Quebrando o problema

Comece por invariantes, não por substantivos bonitos

Boa modelagem protege verdades importantes do sistema.

Exemplos:

  • um pagamento não existe sem pedido
  • um pedido tem itens
  • um usuário não pode ter dois CPFs ativos
  • um cupom expira

Essas são invariantes.

Quando você enxerga isso cedo, a modelagem deixa de ser desenho e vira proteção de regra.

Nem todo campo que “parece importante” merece tabela própria

Esse é um erro muito comum.

Por exemplo, em ecommerce, alguém olha para shipping_address e pensa:

  • “endereço é importante, então deve virar tabela”

Talvez sim.

Talvez não.

Depende de como o sistema usa isso.

Se o endereço do pedido é só um snapshot do momento da compra, talvez ele faça mais sentido como valor embutido no pedido.

Se você precisa reutilizar, editar, validar e relacionar endereços de forma independente, aí cresce a chance de ser entidade própria.

Ou seja:

importância de negócio não implica automaticamente tabela separada.

Padrão de acesso importa tanto quanto regra

Tem time que modela só olhando semântica.

Tem time que modela só olhando CRUD.

Os dois perdem metade da visão.

Vale perguntar:

  • o sistema lê isso junto com o quê?
  • o sistema atualiza isso com que frequência?
  • existe histórico?
  • existe concorrência?
  • existe necessidade de consulta agregada?

Por exemplo:

  • se pedido sempre vem com itens, a relação precisa ser clara
  • se histórico de preço importa, sobrescrever campo não basta
  • se estoque sofre concorrência, a escrita merece cuidado especial

Boa modelagem nasce quando regra de negócio e uso real do dado andam juntos.

Genericão para o futuro quase sempre piora o presente

Outro tropeço comum é criar abstração cedo demais:

  • tabela entities
  • tabela metadata
  • tabela attributes
  • tabela events tentando servir tudo

Isso costuma vir da fantasia:

  • “vai que no futuro precisamos de algo mais genérico”

Só que muitas vezes você compra:

  • query ruim
  • regra espalhada
  • manutenção confusa
  • sistema difícil de explicar

Modelagem boa não é a que prevê qualquer futuro.

É a que aguenta o futuro provável sem destruir a clareza do presente.

Normalização e pragmatismo não são religião

Também vale limpar essa confusão.

Tem hora em que separar ajuda muito:

  • reduz duplicação
  • evita inconsistência
  • deixa regra mais clara

Tem hora em que aproximar ajuda:

  • simplifica leitura
  • reduz join caro
  • guarda snapshot histórico útil

O ponto não é decorar forma normal.

O ponto é saber por que você separou ou aproximou alguma coisa.

Exemplo simples

Imagine um sistema de pedidos.

Jeito confuso de modelar:

  • tudo em orders

  • dados do cliente

  • itens serializados

  • endereço

  • total

  • status

  • pagamento

  • cupom

No começo parece ótimo.

O problema aparece logo:

  • atualizar item vira operação estranha
  • consultar produto mais vendido fica ruim
  • diferenciar snapshot de cliente e cadastro atual vira bagunça
  • pagamento e pedido se embaralham
  • histórico e estado atual ficam misturados

Um modelo melhor poderia separar:

  • customers
  • orders
  • order_items
  • payments

E talvez manter dentro de orders como snapshot:

  • nome do cliente no momento da compra
  • endereço usado naquela compra

Perceba a lógica:

  • customer é entidade
  • order é entidade
  • payment é entidade
  • endereço do pedido talvez seja valor embutido

Não porque alguém decorou uma regra.

Mas porque cada parte tem responsabilidade diferente.

Erros comuns

Criar tabela para qualquer palavra do domínio

Nome conhecido não basta. Precisa existir necessidade de identidade própria.

Centralizar coisa demais em uma tabela só

Parece rápido no início e caro logo depois.

Modelar sem olhar leitura e escrita reais

Schema bom no diagrama pode ser ruim no uso diário.

Inventar abstração antes da hora

Modelo genérico demais costuma dificultar mais do que ajudar.

Falar de normalização como se fosse moral

Separar ou aproximar dado é escolha de engenharia, não demonstração de pureza.

Como um senior pensa

Quem tem mais experiência costuma fazer perguntas bem menos glamourosas e muito mais úteis:

  • o que esse sistema precisa proteger?
  • o que realmente muda junto e o que não muda?
  • onde preciso de identidade própria?
  • quais consultas vão acontecer o tempo todo?
  • onde a inconsistência seria perigosa?

O raciocínio geralmente junta três camadas:

  • regra de negócio
  • padrão de acesso
  • evolução provável

Ele também evita duas vaidades comuns:

  • parecer sofisticado demais
  • parecer rápido demais

Modelagem madura costuma soar mais simples do que muita gente espera.

O que o entrevistador quer ver

Em entrevista, esse tema revela rápido se você pensa em sistema real ou só em diagrama.

O entrevistador normalmente quer ver se você:

  • sabe identificar entidade, relação e cardinalidade
  • conecta estrutura com regra de negócio
  • pensa em leitura e escrita, não só em armazenamento
  • sabe justificar por que algo virou tabela própria ou não
  • evita complicar cedo demais

Uma resposta forte costuma seguir esta linha:

  1. nomear entidades principais
  2. explicar relações
  3. apontar invariantes
  4. mostrar leituras e escritas relevantes
  5. justificar simplificações e limites

Se você fizer isso, já passa muito melhor do que quem começa despejando buzzword de banco.

Modelar entidades não é sair criando tabela para cada substantivo. É decidir o que o sistema realmente precisa reconhecer, relacionar e proteger.

O melhor schema raramente é o mais esperto. Quase sempre é o mais claro que ainda aguenta o trabalho real.

Resumo rápido

O que vale manter na cabeça

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Parte da trilha: Trilha de system design para entrevistas (7/19)

Próximo artigo N+1 query: como perceber e como resolver Artigo anterior Índices: quando ajudam e quando atrapalham

Continue explorando

Artigos relacionados