Guia Completo de Decisão (A vs B vs C)
⚡ Abrir Lista Compacta de Todos os Comandos & Tipos →

Todos os Tipos SQL: Para que servem, Onde usar e O que muda entre A, B ou C

Consulte todos os tipos de campos do banco de dados organizados por categoria funcional. Entenda exatamente para que serve cada tipo, onde aplicar no seu projeto e o que muda na prática se você escolher o tipo A, B ou C na hora de desenhar no DrawDB e programar em PHP.

1. Textos e Caracteres (Strings Curtas e Longas)

Para nomes, documentos, e-mails, senhas, descrições, artigos HTML e observações.

6 Tipos SQL nesta categoria

⚖️ O que muda se eu usar (A) CHAR, (B) VARCHAR ou (C) TEXT?

Comparativo de Impacto Real (A vs B vs C)
A CHAR(11), CHAR(2), CHAR(8)

Opção A: Usar CHAR(n)

🔄 O que muda no banco: O banco reserva SEMPRE o tamanho fixo exato no disco. Se você definir CHAR(10) e gravar "OI", ele preenche com 8 espaços até completar 10.
✅ Vantagem: Mais rápido para leitura e índices quando 100% das linhas têm o mesmo tamanho (CPF, CEP, UF, UUID). Não gasta bytes extras para anotar o tamanho.
⚠️ Cuidado / Limitação: Se usar para nomes ou e-mails (onde cada pessoa tem um tamanho diferente), desperdiça espaço em disco.
🎯 Use SOMENTE quando o tamanho do texto for sempre fixo e igual.
B VARCHAR(120), VARCHAR(255)

Opção B: Usar VARCHAR(n)

🔄 O que muda no banco: O banco grava apenas as letras digitadas + 1 ou 2 bytes que anotam quantas letras foram salvas. Se definir VARCHAR(150) e gravar "Ana", gasta só 4 bytes no disco!
✅ Vantagem: Permite criar índices normais e UNIQUE na coluna inteira, aceita valor DEFAULT e fica armazenado diretamente dentro da linha da tabela (leitura muito rápida).
⚠️ Cuidado / Limitação: Na memória RAM (durante ORDER BY ou tabelas temporárias), o banco pode alocar buffers baseados no limite máximo `n`. Por isso não coloque VARCHAR(5000) se só precisa de VARCHAR(120).
🎯 Use para 90% dos textos do sistema (nomes, e-mails, títulos, telefones, senhas, URLs).
C TEXT, MEDIUMTEXT, LONGTEXT

Opção C: Usar TEXT (TINY / TEXT / MEDIUM / LONG)

🔄 O que muda no banco: O texto não fica guardado junto com as outras colunas da linha! O banco guarda o texto em uma área separada do disco (off-page) e deixa apenas um ponteiro de 20 bytes na tabela.
✅ Vantagem: Permite guardar textos gigantescos (de 64 KB até 4 GB) sem travar a leitura das outras colunas da tabela.
⚠️ Cuidado / Limitação: Mais lento quando precisa recuperar o texto (exige leitura extra no disco), não aceita índice UNIQUE comum sem especificar tamanho de prefixo e é inadequado para buscas com `=` simples.
🎯 Use para textos longos abertos: descrições de produtos, corpo de posts, contratos, observações e HTML.
CHAR(n) 📐 DrawDB: CHAR | Size: n (1 a 255)
💾 Fixo: n caracteres (1 a 255)

📌 Para que serve este Tipo SQL:

Armazenar códigos e siglas que têm SEMPRE a mesma quantidade exata de caracteres em todos os cadastros.

📍 Onde posso usar:

  • • Sigla de Estado / UF: CHAR(2) -> "SP", "RJ", "MG"
  • • CEP sem traço: CHAR(8) -> "01310100"
  • • CPF sem pontos: CHAR(11) -> "01234567890"
  • • CNPJ sem pontos: CHAR(14) -> "12345678000199"
  • • UUID padrão: CHAR(36) | Hash SHA-256: CHAR(64)

⚖️ O que muda se eu escolher este?

Se escolher CHAR em vez de VARCHAR para CPF/UF, você economiza 1 byte de controle por linha e evita fragmentação quando o registro é atualizado.

🐘 PHP PDO: Limpe máscaras com preg_replace('/\D/', '', $valor) e envie com PDO::PARAM_STR.
Ver código SQL/PHP →
VARCHAR(n) 📐 DrawDB: VARCHAR | Size: n (ex: 100, 150, 255)
💾 Variável: tamanho do texto + 1 ou 2 bytes (até 16.383 chars em utf8mb4)

📌 Para que serve este Tipo SQL:

Armazenar textos curtos ou médios cujo comprimento varia de um registro para outro, mas possui um teto máximo conhecido.

📍 Onde posso usar:

  • • Nome de pessoa ou produto: VARCHAR(120)
  • • E-mail de login (com UNIQUE): VARCHAR(150)
  • • Senha com password_hash() do PHP: VARCHAR(255)
  • • Telefone / WhatsApp: VARCHAR(20)
  • • Caminho de imagem / URL: VARCHAR(255)

⚖️ O que muda se eu escolher este?

Se escolher VARCHAR(150) em vez de TEXT, você consegue colocar índice UNIQUE (essencial para e-mail e slug), definir DEFAULT e fazer buscas rápidas por igualdade (`WHERE email = :email`).

🐘 PHP PDO: Valide o limite máximo com mb_strlen($texto, 'UTF-8') <= $n antes de fazer o INSERT.
Ver código SQL/PHP →
TINYTEXT 📐 DrawDB: TINYTEXT | Size: vazio
💾 Até 255 bytes (~255 caracteres) + 1 byte de prefixo

📌 Para que serve este Tipo SQL:

Texto curto armazenado fora da linha principal (raramente necessário hoje em dia).

📍 Onde posso usar:

  • • Notas rápidas ou resumos curtos quando a tabela já atingiu o limite de 65.535 bytes das colunas VARCHAR.

⚖️ O que muda se eu escolher este?

Na prática, quase sempre é melhor usar VARCHAR(255) do que TINYTEXT, pois VARCHAR(255) aceita valor DEFAULT e índices completos nativamente.

🐘 PHP PDO: Prefira VARCHAR(255) a menos que precise aliviar o tamanho interno da linha da tabela.
Ver código SQL/PHP →
TEXT 📐 DrawDB: TEXT | Size: vazio
💾 Até 65.535 bytes (~64 KB — cerca de 15 a 30 páginas de texto)

📌 Para que serve este Tipo SQL:

Armazenar textos longos de vários parágrafos sem poluir a linha principal da tabela.

📍 Onde posso usar:

  • • Descrição detalhada de um produto no e-commerce
  • • Comentários de clientes, avaliações ou mensagens de suporte
  • • Biografia de usuário, prontuário médico ou observações de pedido

⚖️ O que muda se eu escolher este?

Se o texto passar de 64 KB (ex: um artigo imenso com HTML pesado), o MySQL vai cortar ou recusar o INSERT! Se puder passar de 64 KB, mude para MEDIUMTEXT.

🐘 PHP PDO: Envie como string normal via PDO::PARAM_STR. Para buscas por palavra dentro do TEXT, crie um índice FULLTEXT.
Ver código SQL/PHP →
MEDIUMTEXT 📐 DrawDB: MEDIUMTEXT | Size: vazio
💾 Até 16.777.215 bytes (~16 MB de texto)

📌 Para que serve este Tipo SQL:

Armazenar conteúdos editoriais extensos, páginas completas de blog em HTML/Markdown ou templates de documentos.

📍 Onde posso usar:

  • • Corpo completo de notícias, artigos de blog e apostilas em HTML/Markdown
  • • Termos de uso, contratos jurídicos completos
  • • Logs detalhados de erro ou respostas de API externas em texto

⚖️ O que muda se eu escolher este?

Muda o teto de 64 KB (do TEXT comum) para 16 Megabytes, custando apenas 1 byte a mais no cabeçalho do campo (3 bytes em vez de 2). É o tipo ideal para CMS e Blogs!

🐘 PHP PDO: Perfeito para editores ricos (TipTap, Quill, TinyMCE, Markdown) no PHP.
Ver código SQL/PHP →
LONGTEXT 📐 DrawDB: LONGTEXT | Size: vazio
💾 Até 4.294.967.295 bytes (~4 GB de texto)

📌 Para que serve este Tipo SQL:

Capacidade extrema de texto para livros inteiros, transcrições massivas ou dumps de dados.

📍 Onde posso usar:

  • • Acervos literários completos, código-fonte de projetos inteiros ou arquivos XML/CSV gigantes guardados para processamento.

⚖️ O que muda se eu escolher este?

Suporta até 4 GB por célula, mas cuidado no PHP: ler uma coluna LONGTEXT de centenas de megabytes com fetch() comum pode estourar o `memory_limit` do PHP!

🐘 PHP PDO: Evite selecionar colunas LONGTEXT em listagens (faça SELECT apenas das colunas necessárias na tabela).
Ver código SQL/PHP →

2. Números Inteiros (Contagens, Quantidades e Códigos)

Para números sem vírgula: idades, estrelas, estoque, visualizações, anos e IDs.

5 Tipos SQL nesta categoria

⚖️ O que muda se eu usar (A) TINYINT, (B) SMALLINT, (C) INT ou (D) BIGINT? E Signed vs UNSIGNED?

Comparativo de Impacto Real (A vs B vs C)
A Economia Máxima de RAM e Disco

Opção A: TINYINT (1 Byte) ou SMALLINT (2 Bytes)

🔄 O que muda no banco: Você restringe fisicamente o número máximo (255 no TINYINT UNSIGNED; 65.535 no SMALLINT UNSIGNED) e gasta de 50% a 87% menos espaço que um INT ou BIGINT.
✅ Vantagem: Índices menores cabem inteiros na memória RAM do servidor, acelerando filtros em milhões de linhas.
⚠️ Cuidado / Limitação: Se o valor tentar passar do limite (ex: tentar gravar 300 em um TINYINT), o banco rejeita com erro Out of Range.
🎯 Use para valores naturalmente pequenos: idade, estrelas (1-5), dia/mês, parcelas (TINYINT) ou páginas de livro, ano, ordem de exibição (SMALLINT).
B Padrão Equilibrado (Até 2 ou 4 Bilhões)

Opção B: INT / INTEGER (4 Bytes)

🔄 O que muda no banco: Gasta 4 bytes fixos e comporta até 2.147.483.647 (com sinal negativo) ou 4.294.967.295 (UNSIGNED sem sinal negativo).
✅ Vantagem: Atende 99% das quantidades do mundo real (estoque de produtos, duração em segundos, visualizações, IDs de tabelas normais).
⚠️ Cuidado / Limitação: Estoura se você tentar salvar algo acima de 4 bilhões (como telefone com DDD, CPF ou transações de uma rede social gigante).
🎯 Use como padrão para quantidades de estoque, contadores e durações.
C Escala Infinita (Até 18 Quintilhões)

Opção C: BIGINT (8 Bytes) + Diferença UNSIGNED

🔄 O que muda no banco: Gasta 8 bytes por coluna (o dobro do INT), mas nunca esgota sua capacidade numérica. E marcar UNSIGNED proíbe números negativos e dobra o limite positivo!
✅ Vantagem: Zero risco de estourar IDs em tabelas de logs, pedidos, mensagens ou eventos financeiros.
⚠️ Cuidado / Limitação: Gasta o dobro de memória nos índices. E lembre-se: PK e FK precisam ser idênticas (se a PK é BIGINT UNSIGNED, a FK também tem que ser BIGINT UNSIGNED).
🎯 Use para Chaves Primárias (PK/FK) de tabelas grandes e contadores globais.
TINYINT / TINYINT UNSIGNED 📐 DrawDB: TINYINT | Flags: UN (se não aceitar negativo)
💾 1 Byte (8 bits) — De -128 a 127 (Signed) ou 0 a 255 (Unsigned)

📌 Para que serve este Tipo SQL:

Guardar números inteiros muito pequenos cujo valor jamais passará de 255.

📍 Onde posso usar:

  • • Idade de uma pessoa (0 a 150)
  • • Nota de avaliação / estrelas (1 a 5 ou 0 a 10)
  • • Dia da semana (1 a 7), mês do ano (1 a 12)
  • • Número de parcelas no cartão (1 a 24)

⚖️ O que muda se eu escolher este?

Gasta apenas 1 byte (8x menor que um BIGINT). Se marcar UNSIGNED, impede valores negativos como idade -5.

🐘 PHP PDO: Use PDO::PARAM_INT e converta no PHP com (int) $valor.
Ver código SQL/PHP →
SMALLINT / SMALLINT UNSIGNED 📐 DrawDB: SMALLINT | Flags: UN
💾 2 Bytes (16 bits) — De -32.768 a 32.767 (Signed) ou 0 a 65.535 (Unsigned)

📌 Para que serve este Tipo SQL:

Guardar números inteiros pequenos/médios que passam de 255 mas não passam de 65 mil.

📍 Onde posso usar:

  • • Ano de publicação/fabricação (ex: 1500 a 2100)
  • • Quantidade de páginas de um livro ou carga horária de curso
  • • Quantidade de unidades de um item dentro de um pedido
  • • Ordem de exibição de categorias/banners (1, 2, 3...)

⚖️ O que muda se eu escolher este?

Economiza metade do espaço de um INT comum (2 bytes vs 4 bytes) mantendo folga até 65.535.

🐘 PHP PDO: Use PDO::PARAM_INT.
Ver código SQL/PHP →
MEDIUMINT / MEDIUMINT UNSIGNED 📐 DrawDB: MEDIUMINT (Específico do MySQL/MariaDB)
💾 3 Bytes (24 bits) — De -8.388.608 a 8.388.607 ou 0 a 16.777.215 (Unsigned)

📌 Para que serve este Tipo SQL:

Faixa intermediária exclusiva do MySQL para contadores de até 16,7 milhões.

📍 Onde posso usar:

  • • IDs de tabelas de médio porte ou códigos municipais IBGE (7 dígitos) em projetos exclusivamente MySQL.

⚖️ O que muda se eu escolher este?

Se você migrar o banco para PostgreSQL no futuro, o Postgres não tem MEDIUMINT (terá que virar INTEGER de 4 bytes). Na dúvida, use INT.

🐘 PHP PDO: Trabalhe normalmente com int no PHP e PDO::PARAM_INT.
Ver código SQL/PHP →
INT / INTEGER (Signed e UNSIGNED) 📐 DrawDB: INT (ou INTEGER)
💾 4 Bytes (32 bits) — De -2,14 bilhões a +2,14 bilhões (ou 0 a 4,29 bilhões Unsigned)

📌 Para que serve este Tipo SQL:

O inteiro universal padrão de qualquer banco de dados relacional.

📍 Onde posso usar:

  • • Saldo de estoque de produtos (`estoque_atual INT NOT NULL DEFAULT 0`)
  • • Duração de vídeos ou músicas em segundos
  • • Contador de visualizações, downloads ou curtidas
  • • Chaves primárias e estrangeiras de tabelas de até centenas de milhões de linhas

⚖️ O que muda se eu escolher este?

É 100% compatível com todos os bancos (MySQL, PostgreSQL, SQLite, SQL Server) e tem velocidade máxima no processador.

🐘 PHP PDO: Nunca use INT para CPF, CEP ou Telefone (pois apaga zeros à esquerda e estoura 32 bits)!
Ver código SQL/PHP →
BIGINT / BIGINT UNSIGNED 📐 DrawDB: BIGINT | Flags: UN
💾 8 Bytes (64 bits) — Até 9 quintilhões (Signed) ou 18,4 quintilhões (Unsigned)

📌 Para que serve este Tipo SQL:

Números inteiros gigantescos, chaves primárias de alto volume e valores monetários armazenados em centavos.

📍 Onde posso usar:

  • • Chave primária (`id BIGINT UNSIGNED AUTO_INCREMENT`) de pedidos, logs, mensagens, notas fiscais
  • • Contadores globais de redes sociais ou eventos de telemetria
  • • Valores em centavos quando se usa o padrão Money Pattern

⚖️ O que muda se eu escolher este?

Garante que a tabela nunca vai travar por falta de IDs disponíveis, ao custo de usar 8 bytes por coluna em vez de 4.

🐘 PHP PDO: O PHP 8 de 64-bits suporta inteiros de 64-bits nativamente até 9.223.372.036.854.775.807 (PHP_INT_MAX).
Ver código SQL/PHP →

3. Números com Vírgula: Decimais Exatos vs Ponto Flutuante

Para dinheiro, preços, salários, impostos, pesos em kg, medidas e sensores.

3 Tipos SQL nesta categoria

⚖️ O que muda se eu usar (A) DECIMAL, (B) FLOAT ou (C) DOUBLE?

Comparativo de Impacto Real (A vs B vs C)
A Moeda, Preços, Fiscal e Pesos Comerciais

Opção A: Usar DECIMAL(M, D) / NUMERIC(M, D)

🔄 O que muda no banco: O banco guarda o número em base 10 EXATA, dígito por dígito. `0.10 + 0.20` será SEMPRE `0.30` cravado, sem nenhuma dízima oculta.
✅ Vantagem: Zero erro de arredondamento de centavos! Obrigatório por lei/auditoria em qualquer sistema financeiro, de faturamento, estoque ou e-commerce.
⚠️ Cuidado / Limitação: Levemente mais lento para cálculos trigonométricos/científicos pesados do que FLOAT/DOUBLE.
🎯 Use SEMPRE para dinheiro (`DECIMAL(10,2)`), taxas (`DECIMAL(5,2)`) e pesos (`DECIMAL(8,3)`).
B Aproximação Científica Simples

Opção B: Usar FLOAT (4 Bytes)

🔄 O que muda no banco: Converte o número para fração binária (IEEE 754) de 32 bits. Garante apenas ~7 dígitos significativos de precisão.
✅ Vantagem: Gasta apenas 4 bytes e é calculado instantaneamente pelo hardware para gráficos e sensores.
⚠️ Cuidado / Limitação: Se você salvar `19.99`, na memória binária ele pode virar `19.9899997711`. Em somas de 1.000 itens, o valor final fica errado!
🎯 Use apenas para sensores de temperatura, umidade, velocidade ou métricas onde 0,0001 de diferença não importa.
C Aproximação Científica Dupla

Opção C: Usar DOUBLE / REAL (8 Bytes)

🔄 O que muda no banco: Igual ao FLOAT, porém com 64 bits (~15 a 17 dígitos de precisão). Continua sendo binário aproximado.
✅ Vantagem: Excelente para cálculos físicos, astronômicos, estatísticos ou Machine Learning.
⚠️ Cuidado / Limitação: Ainda sofre com `0.1 + 0.2 != 0.3` na base binária, portanto também NÃO deve ser usado para dinheiro.
🎯 Use para cálculos científicos e estatísticos de alta amplitude.
DECIMAL(M, D) / NUMERIC(M, D) 📐 DrawDB: DECIMAL | Size: M,D (ex: 10,2 ou 12,2)
💾 ~4 Bytes a cada 9 dígitos (DECIMAL(10,2) ocupa 5 Bytes)

📌 Para que serve este Tipo SQL:

Armazenar qualquer valor onde cada casa depois da vírgula precisa ser 100% exata. M = total de dígitos; D = casas após a vírgula.

📍 Onde posso usar:

  • • Preços, salários, fretes, descontos: DECIMAL(10, 2) -> até 99.999.999,99
  • • Saldos financeiros grandes: DECIMAL(14, 2)
  • • Peso em quilos/gramas: DECIMAL(8, 3) -> ex: 1,250 kg
  • • Cotações cambiais e criptomoedas: DECIMAL(18, 8)

⚖️ O que muda se eu escolher este?

Garante precisão contábil absoluta. Se tentar gravar 3 casas decimais em um DECIMAL(10,2), o banco arredonda para 2 casas automaticamente.

🐘 PHP PDO: No PDO, passe como string (PDO::PARAM_STR) e some no PHP com bcadd() / bcsub() / bcmul()!
Ver código SQL/PHP →
FLOAT 📐 DrawDB: FLOAT | Size: vazio
💾 4 Bytes (Precisão simples ~7 dígitos)

📌 Para que serve este Tipo SQL:

Medições físicas contínuas e aproximadas que ocupam pouco espaço.

📍 Onde posso usar:

  • • Temperatura ambiente (°C), umidade do ar (%), nível de bateria, leitura de sensores IoT

⚖️ O que muda se eu escolher este?

Ocupa pouco espaço, mas perde precisão a partir do 7º dígito. Nunca faça `WHERE preco = 10.50` em coluna FLOAT.

🐘 PHP PDO: Converta com (float) no PHP.
Ver código SQL/PHP →
DOUBLE / DOUBLE PRECISION 📐 DrawDB: DOUBLE | Size: vazio
💾 8 Bytes (Precisão dupla ~15 a 17 dígitos)

📌 Para que serve este Tipo SQL:

Cálculos científicos, engenharia, pontuação de algoritmos de recomendação e estatística.

📍 Onde posso usar:

  • • Scores de relevância de busca, pesos matemáticos, vetores científicos

⚖️ O que muda se eu escolher este?

Dobra a precisão do FLOAT (usando 8 bytes em vez de 4), evitando estouros em números muito grandes ou muito pequenos.

🐘 PHP PDO: Equivale diretamente ao tipo `float` de 64-bits nativo do PHP.
Ver código SQL/PHP →

4. Datas, Horários e Auditoria de Tempo

Para datas de nascimento, vencimentos, horários de expediente, agendamentos e logs (created_at).

5 Tipos SQL nesta categoria

⚖️ O que muda se eu usar (A) DATE, (B) DATETIME, (C) TIMESTAMP ou (D) TIME?

Comparativo de Impacto Real (A vs B vs C)
A YYYY-MM-DD (3 Bytes)

Opção A: Usar DATE (Só Ano-Mês-Dia)

🔄 O que muda no banco: Guarda exclusivamente o dia do calendário (`2026-10-19`), descartando horas, minutos e fusos horários.
✅ Vantagem: Não sofre distorção de fuso horário (um aniversário ou vencimento de boleto é o mesmo dia em qualquer lugar) e facilita filtrar por dia (`WHERE data_vencimento = CURDATE()`).
⚠️ Cuidado / Limitação: Você não sabe a que horas o registro ocorreu.
🎯 Use para data de nascimento, vencimento de faturas, feriados e admissão.
B YYYY-MM-DD HH:MM:SS (Ano 1000 a 9999)

Opção B: Usar DATETIME (Data + Hora Fixa Civil)

🔄 O que muda no banco: Guarda a data e a hora exatas como uma "fotografia do relógio de parede", sem converter fuso horário, suportando anos de 1000 até 9999.
✅ Vantagem: Nunca muda se o servidor trocar de timezone e não tem o limite do ano 2038 no MySQL para prazos longos (como contratos de 30 anos).
⚠️ Cuidado / Limitação: Gasta 5 a 8 bytes e não converte automaticamente para o fuso horário de usuários em outros países.
🎯 Use para agendamentos futuros (consultas médicas, voos, eventos) e prazos após 2038.
C Auditoria: criado_em / atualizado_em

Opção C: Usar TIMESTAMP (Carimbo de Tempo Universal UTC)

🔄 O que muda no banco: Converte a data/hora enviada para UTC ao gravar no disco e converte de volta para o fuso atual ao fazer SELECT. Ocupa apenas 4 bytes no MySQL.
✅ Vantagem: Perfeito para saber o instante exato no tempo em que algo aconteceu no sistema (`DEFAULT CURRENT_TIMESTAMP`).
⚠️ Cuidado / Limitação: No MySQL, o tipo TIMESTAMP tradicional vai apenas de 1970 até 19/01/2038 (por isso nunca use TIMESTAMP para data de nascimento ou contratos de longo prazo!). No PostgreSQL (`TIMESTAMPTZ`), não existe esse limite.
🎯 Use para colunas de auditoria do sistema: `criado_em`, `atualizado_em`, `deletado_em`, `pago_em`.
DATE 📐 DrawDB: DATE | Size: vazio
💾 3 Bytes — Formato ISO: YYYY-MM-DD (de 1000-01-01 a 9999-12-31)

📌 Para que serve este Tipo SQL:

Registrar datas civis sem horário.

📍 Onde posso usar:

  • • Data de nascimento (`data_nascimento DATE`)
  • • Data de vencimento de boleto/fatura (`data_vencimento DATE`)
  • • Data de emissão contábil ou início de contrato

⚖️ O que muda se eu escolher este?

Ao contrário de salvar em VARCHAR("19/10/2026"), o tipo DATE permite ordenar do mais antigo para o mais novo (`ORDER BY data_vencimento ASC`) e somar dias (`DATE_ADD`).

🐘 PHP PDO: Salve sempre como Y-m-d e exiba na tela com DateTimeImmutable::createFromFormat('Y-m-d', $val)->format('d/m/Y').
Ver código SQL/PHP →
TIME 📐 DrawDB: TIME | Size: vazio
💾 3 Bytes — Formato: HH:MM:SS

📌 Para que serve este Tipo SQL:

Guardar apenas o horário do relógio (sem dia/mês/ano) ou um intervalo de duração.

📍 Onde posso usar:

  • • Horário de abertura e fechamento de uma loja (`08:00:00` às `18:00:00`)
  • • Horário fixo de início de uma aula ou turno de trabalho

⚖️ O que muda se eu escolher este?

Permite consultar facilmente "quais lojas estão abertas agora" comparando `CURTIME() BETWEEN abre_as AND fecha_as`.

🐘 PHP PDO: Envie no formato H:i:s (ex: "14:30:00") com PDO::PARAM_STR.
Ver código SQL/PHP →
DATETIME 📐 DrawDB: DATETIME | Size: vazio
💾 5 a 8 Bytes — De 1000-01-01 00:00:00 a 9999-12-31 23:59:59

📌 Para que serve este Tipo SQL:

Registrar data e hora completas sem conversão de fuso horário e sem limite de ano 2038.

📍 Onde posso usar:

  • • Data e hora de agendamentos (`data_hora_consulta DATETIME`)
  • • Início e fim de promoções, eventos ou validade de certificados longos

⚖️ O que muda se eu escolher este?

Guarda exatamente a data/hora enviada pelo PHP, independentemente do timezone configurado no servidor MySQL.

🐘 PHP PDO: Configure date_default_timezone_set('America/Sao_Paulo') no PHP e formate com format('Y-m-d H:i:s').
Ver código SQL/PHP →
TIMESTAMP 📐 DrawDB: TIMESTAMP | Default: CURRENT_TIMESTAMP
💾 4 Bytes (MySQL) / 8 Bytes (PostgreSQL TIMESTAMPTZ)

📌 Para que serve este Tipo SQL:

Carimbo de tempo automático de quando um registro foi criado, alterado ou excluído.

📍 Onde posso usar:

  • • Auditoria automática: `criado_em TIMESTAMP DEFAULT CURRENT_TIMESTAMP`
  • • Última alteração: `atualizado_em TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`
  • • Exclusão lógica (Soft Delete): `deletado_em TIMESTAMP NULL`

⚖️ O que muda se eu escolher este?

Converte para UTC internamente e é mais leve (4 bytes), mas no MySQL não aceita datas antes de 1970 nem depois de 2038.

🐘 PHP PDO: Deixe o próprio banco preencher no INSERT usando DEFAULT CURRENT_TIMESTAMP!
Ver código SQL/PHP →
YEAR 📐 DrawDB: YEAR (MySQL) ou SMALLINT
💾 1 Byte (Anos de 1901 a 2155)

📌 Para que serve este Tipo SQL:

Guardar exclusivamente um número de ano com 4 dígitos gastando apenas 1 byte.

📍 Onde posso usar:

  • • Ano de exercício fiscal, ano letivo escolar ou ano de fabricação (entre 1901 e 2155).

⚖️ O que muda se eu escolher este?

Economiza 1 byte em relação ao SMALLINT, mas só existe no MySQL/MariaDB e só vai de 1901 a 2155. Se precisar de anos antigos (ex: 1850) ou usar PostgreSQL, use SMALLINT.

🐘 PHP PDO: Envie como inteiro de 4 dígitos (ex: 2026).
Ver código SQL/PHP →

5. Booleanos, Listas de Opções (ENUM/SET) e Documentos JSON

Para flags de verdadeiro/falso, status de pedidos, níveis de acesso e configurações flexíveis.

5 Tipos SQL nesta categoria

⚖️ O que muda se eu usar (A) ENUM, (B) VARCHAR com Enum no PHP ou (C) Tabela Separada (FK)?

Comparativo de Impacto Real (A vs B vs C)
A ENUM('pendente', 'pago', 'cancelado')

Opção A: Usar ENUM no Banco

🔄 O que muda no banco: O próprio banco de dados trava os valores permitidos e grava internamente como um número de 1 byte (super compacto).
✅ Vantagem: Impede que qualquer script grave um status inválido no banco e ocupa apenas 1 byte por linha.
⚠️ Cuidado / Limitação: Para adicionar ou remover uma opção no futuro, você precisa rodar um `ALTER TABLE` na estrutura do banco.
🎯 Use para listas pequenas e imutáveis (ex: PF/PJ, status básicos do sistema).
B Flexibilidade de Código sem ALTER TABLE

Opção B: Usar VARCHAR(30) + BackedEnum no PHP 8

🔄 O que muda no banco: A coluna no banco é um `VARCHAR(30) NOT NULL`, e quem valida as opções permitidas é o `enum Status: string` nativo do PHP 8.1+.
✅ Vantagem: Se surgir um novo status amanhã, basta adicionar 1 linha no Enum do PHP sem precisar alterar a tabela no banco de dados!
⚠️ Cuidado / Limitação: Ocupa alguns bytes a mais no disco (o tamanho da palavra em vez de 1 byte).
🎯 Excelente para projetos ágeis em PHP 8 onde novos status surgem com frequência.
C tabela_id INT UNSIGNED (Relacional)

Opção C: Criar uma Tabela Separada com Foreign Key

🔄 O que muda no banco: As opções ficam cadastradas como linhas em uma tabela própria (ex: `categorias` ou `departamentos`) e são ligadas por chave estrangeira.
✅ Vantagem: O próprio cliente/administrador pode criar, renomear ou desativar opções pelo painel do sistema sem mexer em código nem banco!
⚠️ Cuidado / Limitação: Exige um `JOIN` na hora de buscar o nome da opção.
🎯 Obrigatório sempre que o usuário puder cadastrar novas opções pelo sistema!
BOOLEAN / BOOL / TINYINT(1) 📐 DrawDB: BOOLEAN (ou TINYINT Size: 1)
💾 1 Byte — Valores: 0 (Falso) ou 1 (Verdadeiro)

📌 Para que serve este Tipo SQL:

Guardar respostas de Sim/Não, Ativo/Inativo, Ligado/Desligado.

📍 Onde posso usar:

  • • Cadastro ativo (`ativo BOOLEAN NOT NULL DEFAULT 1`)
  • • Produto em destaque (`destaque BOOLEAN NOT NULL DEFAULT 0`)
  • • Frete grátis (`frete_gratis BOOLEAN NOT NULL DEFAULT 0`)

⚖️ O que muda se eu escolher este?

Ocupa apenas 1 byte e torna os filtros no PHP super limpos. Dica: se além de saber SE foi feito você precisar saber QUANDO foi feito (ex: e-mail verificado), troque `email_verificado BOOLEAN` por `email_verificado_em TIMESTAMP NULL`!

🐘 PHP PDO: No PDO, envie `$ativo ? 1 : 0` com `PDO::PARAM_INT` para total compatibilidade.
Ver código SQL/PHP →
BIT(n) 📐 DrawDB: BIT | Size: 1 a 64
💾 Aproximadamente (n + 7) / 8 Bytes

📌 Para que serve este Tipo SQL:

Armazenar máscaras de bits puras (flags binárias compactadas).

📍 Onde posso usar:

  • • Sistemas legados ou máscaras de permissões binárias (b'0101').

⚖️ O que muda se eu escolher este?

Se escolher `BIT(1)` em vez de `BOOLEAN`/`TINYINT(1)` no MySQL, o PDO em PHP pode retornar o valor como um caractere binário invisível (`"\x00"` ou `"\x01"`), causando bugs em `if ($row['ativo'])`! Por isso, prefira sempre `BOOLEAN` / `TINYINT(1)` no MySQL.

🐘 PHP PDO: Evite BIT(1) em PHP; use BOOLEAN / TINYINT(1).
Ver código SQL/PHP →
ENUM('a', 'b', 'c') 📐 DrawDB: ENUM | Values: 'pendente','pago','cancelado'
💾 1 Byte (até 255 opções) ou 2 Bytes

📌 Para que serve este Tipo SQL:

Permitir que a coluna receba exatamente UM valor dentre uma lista fechada.

📍 Onde posso usar:

  • • Status de pedido: ENUM('pendente', 'pago', 'enviado', 'cancelado')
  • • Tipo de pessoa: ENUM('PF', 'PJ')
  • • Método de pagamento: ENUM('pix', 'cartao', 'boleto')

⚖️ O que muda se eu escolher este?

O banco valida automaticamente a opção enviada e economiza espaço gravando apenas o índice numérico internamente.

🐘 PHP PDO: Combine com `enum MeuStatus: string` do PHP 8.1+.
Ver código SQL/PHP →
SET('a', 'b', 'c') 📐 DrawDB: SET | Values: 'seg','ter','qua','qui','sex'
💾 1 a 8 Bytes (até 64 opções combináveis)

📌 Para que serve este Tipo SQL:

Permitir escolher ZERO, UM ou VÁRIOS valores ao mesmo tempo de uma lista pré-definida.

📍 Onde posso usar:

  • • Dias da semana de um alarme ou características simples fixas.

⚖️ O que muda se eu escolher este?

Difícil de filtrar individualmente e só existe no MySQL. Na prática moderna, é muito melhor usar uma coluna `JSON` (ex: `["seg", "qua"]`) ou uma tabela relacional N:N!

🐘 PHP PDO: Prefira JSON ou tabela associativa N:N em vez de SET.
Ver código SQL/PHP →
JSON / JSONB 📐 DrawDB: JSON (ou JSONB no PostgreSQL)
💾 Variável em formato binário otimizado (até 1 GB / 4 GB)

📌 Para que serve este Tipo SQL:

Guardar arrays, objetos aninhados e atributos variáveis sem precisar criar dezenas de colunas vazias.

📍 Onde posso usar:

  • • Ficha técnica variável de produtos (ex: especificações de celular vs roupa)
  • • Preferências de interface do usuário, logs de auditoria (valores antigos vs novos)
  • • Retorno bruto de gateways de pagamento (Webhooks)

⚖️ O que muda se eu escolher este?

Se escolher `JSON` em vez de `TEXT`, o banco impede salvar um JSON com erro de sintaxe e permite consultar campos internos direto no SQL (`WHERE atributos->>"$.voltagem" = "220v"`). Mas nunca use JSON para guardar chaves estrangeiras!

🐘 PHP PDO: Use `json_encode($dados, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR)` e `json_decode($json, true)`.
Ver código SQL/PHP →

6. Binários, Arquivos (BLOBs) e Coordenadas de Mapa (Geo)

Para bytes criptográficos, endereços IP compactados, anexos e coordenadas GPS.

4 Tipos SQL nesta categoria

⚖️ O que muda se eu salvar fotos/PDFs em (A) VARCHAR (Caminho/URL) vs (B) BLOB (Dentro do Banco)?

Comparativo de Impacto Real (A vs B vs C)
A Arquitetura Profissional Rápida

Opção A: Usar VARCHAR(255) com o Caminho/URL do Arquivo (RECOMENDADO)

🔄 O que muda no banco: O arquivo físico (.jpg, .webp, .pdf) é salvo em uma pasta `/uploads` do servidor ou em nuvem (S3 / Cloudflare R2), e o banco guarda apenas o texto `"uploads/foto-123.webp"` (30 bytes!).
✅ Vantagem: O banco de dados continua super leve (poucos megabytes), os backups rodam em segundos e o navegador carrega as imagens direto com cache.
⚠️ Cuidado / Limitação: Ao apagar o registro no banco, seu código PHP também deve apagar o arquivo da pasta (ou manter rotina de limpeza).
🎯 Use em 99% dos sistemas web para fotos de perfil, imagens de produtos, vídeos e PDFs.
B Bytes Brutos dentro da Tabela

Opção B: Usar BLOB / MEDIUMBLOB / LONGBLOB (Arquivo dentro do Banco)

🔄 O que muda no banco: Os milhões de bytes da imagem ou PDF são gravados diretamente dentro da tabela SQL.
✅ Vantagem: O arquivo vai junto automaticamente no mesmo `mysqldump` e fica protegido pelas mesmas transações ACID do banco.
⚠️ Cuidado / Limitação: Deixa o banco gigabytes mais pesado, consome a memória RAM de cache do SQL e exige um script PHP intermediário para ler os bytes toda vez que exibir a imagem.
🎯 Use apenas para arquivos minúsculos e ultra-confidenciais (como certificados digitais A1 `.pfx` ou chaves criptográficas).
C Hashes, UUID Compacto e Endereços IP

Opção C: Usar BINARY(16) / VARBINARY(16)

🔄 O que muda no banco: Guarda bytes curtos de tamanho exato sem codificação de texto.
✅ Vantagem: Um UUID em `BINARY(16)` ocupa metade do espaço de um `CHAR(36)` (16 bytes vs 36 bytes), e um IP em `VARBINARY(16)` ocupa apenas 4 a 16 bytes em vez de `VARCHAR(45)`.
⚠️ Cuidado / Limitação: Exige funções de conversão (`BIN_TO_UUID` / `inet_ntop`) para ler como texto humano.
🎯 Use quando precisar de altíssima performance em tabelas com dezenas de milhões de IPs ou hashes.
BINARY(n) / VARBINARY(n) 📐 DrawDB: BINARY ou VARBINARY | Size: n (ex: 16, 32)
💾 Fixo (BINARY) ou Variável (VARBINARY) em bytes puros

📌 Para que serve este Tipo SQL:

Armazenar sequências curtas de bytes brutos (sem tabela de caracteres/acentos).

📍 Onde posso usar:

  • • Endereços IPv4 e IPv6 compactados com `inet_pton()`: VARBINARY(16)
  • • UUID compactado em bytes: BINARY(16)
  • • Hash SHA-256 binário puro: BINARY(32)

⚖️ O que muda se eu escolher este?

Compara byte a byte (muito mais rápido que comparar texto com collation UTF-8) e economiza até 55% de espaço em hashes e UUIDs.

🐘 PHP PDO: Use `inet_pton($ip)` e `inet_ntop($bin)` no PHP para IPs.
Ver código SQL/PHP →
TINYBLOB / BLOB / MEDIUMBLOB / LONGBLOB 📐 DrawDB: BLOB (ou MEDIUMBLOB / LONGBLOB)
💾 TINYBLOB: 255 B | BLOB: 64 KB | MEDIUMBLOB: 16 MB | LONGBLOB: 4 GB

📌 Para que serve este Tipo SQL:

Armazenar arquivos binários ou dados criptografados diretamente no banco.

📍 Onde posso usar:

  • • Certificados digitais fiscais (.pfx) criptografados, assinaturas biométricas compactas

⚖️ O que muda se eu escolher este?

Diferente do TEXT, o BLOB não possui charset/collation (guarda bytes puros). Evite usar para fotos públicas do site (prefira salvar no disco e guardar a URL em VARCHAR).

🐘 PHP PDO: Use `PDO::PARAM_LOB` ao fazer bind de streams ou bytes binários.
Ver código SQL/PHP →
POINT (Geolocalização Espacial) 📐 DrawDB: POINT (ou 2 colunas DECIMAL 10,8 e 11,8)
💾 25 Bytes (Interno WKB + SRID)

📌 Para que serve este Tipo SQL:

Guardar um ponto geográfico (Longitude e Latitude) para cálculos nativos de distância em mapas.

📍 Onde posso usar:

  • • Localização de lojas, entregadores ou imóveis para buscar "todos num raio de 5 km"

⚖️ O que muda se eu escolher este?

Se usar 2 colunas `DECIMAL(10,8)` e `DECIMAL(11,8)`, é muito mais simples de ler e gravar no PHP. Se usar `POINT`, você ganha o poder de criar um `SPATIAL INDEX` e usar `ST_Distance_Sphere()` no SQL!

🐘 PHP PDO: Para simplicidade em 95% dos projetos, duas colunas `latitude DECIMAL(10,8)` e `longitude DECIMAL(11,8)` são mais fáceis de manter no DrawDB e no PHP.
Ver código SQL/PHP →
POLYGON / GEOMETRY 📐 DrawDB: POLYGON ou GEOMETRY
💾 Variável conforme o número de vértices do mapa

📌 Para que serve este Tipo SQL:

Desenhar áreas fechadas no mapa (bairros, zonas de taxa de entrega, fazendas).

📍 Onde posso usar:

  • • Verificar se o ponto GPS da casa do cliente cai dentro da área de cobertura de entrega (`ST_Contains`).

⚖️ O que muda se eu escolher este?

Permite que o próprio banco de dados responda se uma coordenada está dentro ou fora de um polígono desenhado no mapa.

🐘 PHP PDO: Use funções `ST_GeomFromText` ou `ST_GeomFromGeoJSON` nas consultas PDO.
Ver código SQL/PHP →