DBAtlas · Atlas de operações de banco de dados

Decisão: escolha o tipo de dado certo

Escolher um tipo de dado é uma das decisões mais caras de corrigir depois: o tipo errado produz resultados errados (ex.: float para dinheiro), desperdício de espaço e consultas lentas. Esta árvore orienta você para o tipo certo para campos numéricos, de texto, de data/hora, de chave (PK), semiestruturados (JSON) e de categoria (ENUM), e destaca armadilhas clássicas como dinheiro e character sets.

Que tipo de dado você está armazenando?

O tipo certo é determinado pela natureza do dado. Em qual categoria o campo se enquadra: um número, texto, uma data/hora, a chave primária da tabela, dados flexíveis/semiestruturados (JSON) ou um conjunto limitado de categorias?

  • Valor numérico (quantidade, dinheiro, medida, contador)
  • Texto (nome, descrição, código)
  • Data e/ou hora
  • Estou projetando uma chave primária (PK)
  • Campos flexíveis/aninhados/variáveis (dados semiestruturados)
  • Um conjunto limitado e conhecido de categorias (status, tipo, prioridade)

O número é inteiro ou decimal — e é dinheiro?

Para numéricos, a distinção mais crítica é a exatidão. O valor é inteiro (quantidade, ID, contador) ou decimal? Se for decimal, é DINHEIRO/um valor financeiro? Ponto flutuante binário (FLOAT/DOUBLE) nunca é usado para dinheiro nem onde se exige exatidão, porque produz erros de arredondamento.

  • Inteiro (quantidade, contador, id)
  • Dinheiro ou decimal exato (preço, saldo, taxa)

Recomendação: inteiro (SMALLINT / INT / BIGINT)

Para inteiros, escolha o menor tipo que cubra o intervalo necessário. Um tipo desnecessariamente grande desperdiça espaço e tamanho de índice; mas, para campos que podem crescer, como contadores/PKs, largura suficiente é essencial para evitar overflow.

Recomendação: NUMERIC / DECIMAL — NUNCA FLOAT para dinheiro

Para dinheiro e decimais exatos, use NUMERIC/DECIMAL de ponto fixo (exato). FLOAT/DOUBLE são ponto flutuante binário e não conseguem armazenar valores como 0.1 com exatidão; somas/multiplicações produzem desvios de centavos, saldos errados e problemas de auditoria.

Recomendação: texto — VARCHAR vs TEXT vs CHAR

Para texto, usa-se VARCHAR/TEXT para comprimento variável e CHAR para comprimento realmente fixo. Nos engines modernos, a diferença de armazenamento entre VARCHAR e TEXT é em geral desprezível; a decisão real é se deve haver um limite semântico (uma restrição de comprimento).

Recomendação: data/hora — TIMESTAMP com fuso horário

Se você armazena um instante (o horário de um evento), escolha um tipo que considere o fuso horário. Armazenar sem fuso horário leva a cálculos e comparações errados entre regiões/mudanças de horário de verão.

Recomendação: chave primária — BIGINT vs UUID

Há duas opções principais para uma PK: um número crescente (BIGINT identity/sequence) ou um UUID. Uma PK numérica é pequena e amigável ao índice, mas previsível e exige geração centralizada; um UUID pode ser gerado de forma distribuída, mas é maior e sua ordem aleatória pode prejudicar o índice.

Recomendação: JSON / JSONB — use com moderação

O tipo JSON é poderoso para campos com schema flexível, aninhados ou esparsos; mas a disciplina relacional (constraints, índices, segurança de tipos) pode se perder. Regra: mova os campos fixos e consultados com frequência para colunas normais e mantenha no JSON apenas a parte realmente variável.

Recomendação: ENUM vs tabela de lookup (referência)

Há duas opções para conjuntos limitados de categorias: o tipo ENUM do engine, ou uma tabela de lookup + foreign key. O ENUM é compacto e simples, mas adicionar um valor exige uma alteração de schema; uma tabela de lookup é flexível e pode carregar atributos extras (descrição, flag de ativo, ordem).

Abrir no DBAtlas →