Cinco Storage Classes, Não Vários Tipos
No SQLite, todo valor é guardado em uma das cinco storage classes:
NULL— a ausência de valor.INTEGER— um número inteiro com sinal, ocupando de 1 a 8 bytes conforme o tamanho.REAL— um número de ponto flutuante IEEE de 8 bytes.TEXT— uma string, armazenada na codificação do banco (geralmente UTF-8).BLOB— bytes brutos, gravados exatamente como você passou.
É só isso. Não existe um BOOLEAN separado, nem DATETIME, nem VARCHAR, nem DECIMAL. Outros bancos oferecem dezenas de tipos; o SQLite tem cinco, e todo o resto é construído em cima deles.
typeof() mostra a storage class real de cada valor. Você vai ver integer, real, text, blob. Essas quatro — mais null — são tudo o que o SQLite conhece.
Tipagem dinâmica no SQLite
Aqui vem a parte que costuma pegar de surpresa quem vem do Postgres ou do MySQL. No SQLite (sem usar STRICT), o tipo declarado na coluna é mais uma sugestão do que uma regra. O tipo de verdade fica grudado em cada valor:
Ambas as linhas foram aceitas. A coluna id guarda um inteiro em uma linha e texto em outra; body guarda texto e um inteiro. O SQLite armazena, sem reclamar, valores de qualquer classe em qualquer coluna.
Isso é tipagem dinâmica, e é uma escolha de design proposital. Torna o SQLite bastante tolerante para protótipos e scripts rápidos. Mas também significa que um erro de digitação no código da sua aplicação pode salvar dados no formato errado silenciosamente, durante anos. Se esse trade-off te incomoda — e em quase todo schema de produção deveria incomodar mesmo — as tabelas STRICT são a solução. Já vamos chegar nelas.
Afinidade de tipos em um parágrafo
O tipo declarado da coluna não é ignorado; ele dá à coluna uma afinidade. Quando você insere um valor, o SQLite tenta convertê-lo para a afinidade da coluna, desde que a conversão seja limpa. Uma coluna TEXT que recebe o número 42 guarda como texto '42'; uma coluna INTEGER que recebe a string '42' guarda como inteiro 42. Se a conversão fosse perder informação, o tipo original é mantido.
Linha um: o inteiro 42 foi convertido para o texto '42', e a string '100' virou o inteiro 100. Linha dois: o '3.5' não cabia em INTEGER sem perda, então ficou como texto mesmo. A afinidade tem uma página própria mais adiante — por enquanto, basta saber que o tipo da coluna ainda influencia o armazenamento, mesmo sem forçar nada.
Boolean no SQLite
Não existe storage class BOOLEAN. O SQLite guarda valores booleanos como inteiros — 0 para falso e 1 para verdadeiro:
As palavras-chave TRUE e FALSE são reconhecidas (a partir do SQLite 3.23) e equivalem a 1 e 0. Declarar uma coluna como BOOLEAN dá a ela afinidade numérica, mas não restringe os valores a 0 ou 1 — sem STRICT, dá pra inserir 'maybe' que o SQLite aceita numa boa.
Datas e horas no SQLite
Também não existe um tipo DATETIME. Você escolhe uma entre três formas de codificação, e as funções de data do SQLite funcionam com qualquer uma delas:
TEXTno formato ISO-8601:'2026-04-23 14:30:00'.REALcomo número de dia juliano.INTEGERcomo segundos do Unix epoch.
Texto em ISO-8601 é a escolha mais comum — ordena corretamente como string, é legível e todas as funções nativas (date(), time(), datetime(), strftime(), julianday()) trabalham com esse formato. Escolha um padrão por coluna e mantenha — misturar formatos diferentes na mesma coluna é o tipo de coisa que vai te morder seis meses depois.
VARCHAR, CHAR e outros nomes familiares
O SQLite aceita os nomes de tipo que você já conhece de outros bancos — VARCHAR(255), CHAR(10), NVARCHAR, DECIMAL(10,2), DOUBLE, FLOAT, INT, BIGINT, MEDIUMINT. Todos são reconhecidos sem problema. A diferença é que, internamente, eles caem em uma das cinco storage classes seguindo as regras de afinidade.
VARCHAR(255) não impõe limite de 255 caracteres — o SQLite simplesmente ignora o tamanho. DECIMAL(10, 2) também não guarda um decimal de precisão fixa — ele recebe afinidade numérica e acaba armazenado como INTEGER ou REAL. Esses nomes existem só para que esquemas copiados de outros bancos rodem sem reclamação; eles não trazem junto as restrições que esses mesmos nomes teriam em outros lugares.
Se você precisa de aritmética decimal exata para valores monetários, guarde centavos como INTEGER. Cedo ou tarde, o REAL (ponto flutuante) vai introduzir erros de arredondamento já na terceira casa decimal.
NULL é uma storage class
NULL não é apenas "ausência de valor" — é um valor com sua própria storage class, devolvida pelo typeof():
b aparece como null. Isso importa porque NULL não é igual a nada — nem mesmo a outro NULL. b = NULL nunca é verdadeiro; o jeito certo é escrever b IS NULL. Esse detalhe volta com mais calma na página sobre operadores e null, mas a história começa aqui, na storage class.
Armazenando bytes com o tipo BLOB no SQLite
BLOB guarda bytes brutos exatamente como você passou — ideal para imagens pequenas, hashes, dados codificados, qualquer coisa que não seja texto nem número:
O literal x'...' permite escrever blobs em hexadecimal direto no SQL; já no código da aplicação, o normal é passar um array de bytes via parâmetro. O length() em um blob devolve a contagem de bytes, não de caracteres.
Uma observação prática: o SQLite aguenta numa boa armazenar blobs grandes, mas puxar um blob de 50 MB em toda consulta que toca aquela linha vai ficar lento. Para arquivos grandes, o ideal é guardar o arquivo em disco e manter só o caminho no banco.
O que fica de aprendizado
- As cinco storage classes —
NULL,INTEGER,REAL,TEXTeBLOB— cobrem tudo no SQLite. - Boolean no SQLite é inteiro; datetime pode ser texto, real ou inteiro (você escolhe).
- Os tipos declarados nas colunas são dicas, não contratos (a menos que você use
STRICT). VARCHAR(255)e companhia até são aceitos na sintaxe, mas não impõem o tamanho ou a precisão que sugerem em outros bancos.typeof(valor)é seu melhor amigo sempre que bater dúvida sobre o que está realmente armazenado.
A seguir: Type Affinity
Esse comportamento de "dica" que passamos por cima tem uma regra bem definida por trás — cinco classes de afinidade, derivadas do nome do tipo declarado, aplicadas a cada inserção. Esse é o tema da próxima página, e é justamente a chave para prever o que o SQLite vai de fato fazer com os valores que você entrega a ele.
Perguntas frequentes
Quais tipos de dados o SQLite suporta?
O SQLite trabalha com cinco storage classes: NULL, INTEGER, REAL, TEXT e BLOB. Todo valor gravado no banco cai em uma dessas categorias. Nomes conhecidos como VARCHAR(255), DATETIME ou BOOLEAN até funcionam dentro do CREATE TABLE (por compatibilidade), mas na hora de armazenar são reduzidos a um desses cinco tipos.
O SQLite tem tipo boolean ou datetime?
Não como storage classes separadas. Booleanos viram INTEGER (0 e 1), embora o SQLite também aceite as palavras-chave TRUE e FALSE. Já datas e horas podem ser guardadas como TEXT (strings ISO-8601), REAL (dia juliano) ou INTEGER (segundos do Unix epoch) — você escolhe a representação e as funções de data continuam funcionando nas três.
Por que dizem que a tipagem do SQLite é dinâmica?
Na maioria dos bancos, uma coluna declarada como INTEGER rejeita strings. No SQLite (no modo padrão), o tipo declarado é só uma dica — quem carrega o tipo de verdade é o próprio valor. Ou seja, dá pra inserir um inteiro numa coluna TEXT sem reclamação. Isso ora ajuda, ora vira tiro no pé. Se quiser o comportamento rígido, use tabelas STRICT.