Tipos de dados no PostgreSQL: texto, números, datas e booleanos
1. Introdução aos tipos de dados no PostgreSQL
A escolha correta dos tipos de dados no PostgreSQL é fundamental para garantir integridade, performance e eficiência no armazenamento. Cada tipo de dado determina como o banco armazena, valida e processa as informações, impactando diretamente a velocidade das consultas e o espaço em disco utilizado.
Os tipos de dados no PostgreSQL se dividem em quatro categorias principais:
- Texto: para armazenar caracteres e strings
- Numérico: para valores inteiros e decimais
- Data/Hora: para datas, horas e intervalos
- Lógico: para valores booleanos
Boas práticas ao escolher tipos incluem: usar o tipo mais específico possível, evitar superdimensionamento, considerar a necessidade de precisão em cálculos financeiros e planejar o crescimento futuro dos dados.
2. Tipos de dados de texto
O PostgreSQL oferece três tipos principais para armazenamento de texto:
CHAR(n) armazena strings de comprimento fixo. Se o valor for menor que n, o PostgreSQL preenche com espaços à direita. Ideal para códigos padronizados, como siglas de estados:
CREATE TABLE exemplo_char (
sigla_estado CHAR(2)
);
INSERT INTO exemplo_char VALUES ('SP');
-- 'SP' será armazenado como 'SP' (2 caracteres)
VARCHAR(n) armazena strings de comprimento variável até o limite n. Diferente do CHAR, não faz padding com espaços:
CREATE TABLE exemplo_varchar (
nome VARCHAR(50)
);
INSERT INTO exemplo_varchar VALUES ('Maria Silva');
-- Ocupa apenas 11 caracteres, respeitando o limite de 50
TEXT não possui limite de tamanho, podendo armazenar até 1 GB. Recomendado para descrições longas, comentários e textos imprevisíveis:
CREATE TABLE exemplo_text (
descricao TEXT
);
INSERT INTO exemplo_text VALUES ('Texto longo sem restrição de tamanho...');
Operações comuns com strings:
-- Concatenação
SELECT 'Olá' || ' ' || 'Mundo' AS saudacao;
-- Funções de string
SELECT UPPER('postgresql') AS maiusculo; -- POSTGRESQL
SELECT LOWER('SQL') AS minusculo; -- sql
SELECT LENGTH('Banco de Dados') AS tamanho; -- 14
3. Tipos de dados numéricos
Inteiros possuem faixas específicas de valores:
| Tipo | Faixa | Armazenamento |
|---|---|---|
SMALLINT |
-32.768 a 32.767 | 2 bytes |
INTEGER |
-2.147.483.648 a 2.147.483.647 | 4 bytes |
BIGINT |
-9.223.372.036.854.775.808 a 9.223.372.036.854.775.807 | 8 bytes |
CREATE TABLE produtos (
id INTEGER,
quantidade_estoque SMALLINT,
populacao_mundial BIGINT
);
Decimais e ponto flutuante oferecem diferentes níveis de precisão:
NUMERIC(p, s) — precisão exata, ideal para valores financeiros:
- p = número total de dígitos (precisão)
- s = número de dígitos decimais (escala)
CREATE TABLE contas (
saldo NUMERIC(10,2) -- 10 dígitos no total, 2 decimais
);
INSERT INTO contas VALUES (12345.67);
REAL e DOUBLE PRECISION — ponto flutuante, maior performance mas menos precisão:
- REAL: 6 dígitos decimais de precisão (4 bytes)
- DOUBLE PRECISION: 15 dígitos decimais de precisão (8 bytes)
CREATE TABLE medicao (
temperatura REAL,
distancia DOUBLE PRECISION
);
Exemplo prático de precisão financeira:
-- NUMERIC mantém precisão exata
SELECT 0.1::NUMERIC + 0.2::NUMERIC; -- 0.3
-- DOUBLE PRECISION pode ter pequenos erros de arredondamento
SELECT 0.1::DOUBLE PRECISION + 0.2::DOUBLE PRECISION; -- 0.30000000000000004
4. Tipos de dados de data e hora
O PostgreSQL oferece tipos robustos para trabalhar com datas e horas:
| Tipo | Descrição | Exemplo |
|---|---|---|
DATE |
Data (ano, mês, dia) | '2024-01-15' |
TIME |
Hora (sem fuso) | '14:30:00' |
TIMESTAMP |
Data e hora (sem fuso) | '2024-01-15 14:30:00' |
TIMESTAMPTZ |
Data e hora (com fuso) | '2024-01-15 14:30:00-03' |
INTERVAL |
Período de tempo | '2 days 3 hours' |
CREATE TABLE eventos (
data_evento DATE,
horario TIME,
criado_em TIMESTAMP,
atualizado_em TIMESTAMPTZ,
duracao INTERVAL
);
Funções úteis para manipulação de datas:
-- Data e hora atuais
SELECT NOW() AS agora; -- 2024-01-15 14:30:00.123456-03
SELECT CURRENT_DATE AS hoje; -- 2024-01-15
SELECT CURRENT_TIME AS hora_atual; -- 14:30:00.123456-03
-- Cálculo de idade entre datas
SELECT AGE('2024-01-15', '1990-05-20') AS idade; -- 33 years 7 mons 26 days
-- Extração de partes da data
SELECT EXTRACT(YEAR FROM NOW()) AS ano;
SELECT EXTRACT(MONTH FROM NOW()) AS mes;
SELECT EXTRACT(DAY FROM NOW()) AS dia;
-- Operações aritméticas com INTERVAL
SELECT CURRENT_DATE + INTERVAL '30 days' AS data_futura;
SELECT CURRENT_DATE - INTERVAL '1 year' AS ano_passado;
5. Tipo booleano
O tipo BOOLEAN no PostgreSQL aceita três valores: TRUE, FALSE e NULL.
CREATE TABLE usuarios (
id INTEGER,
nome TEXT,
ativo BOOLEAN
);
INSERT INTO usuarios VALUES
(1, 'João', TRUE),
(2, 'Maria', FALSE),
(3, 'Pedro', NULL);
Uso em condições e operadores lógicos:
-- WHERE com booleano
SELECT * FROM usuarios WHERE ativo = TRUE;
SELECT * FROM usuarios WHERE ativo; -- Sintaxe simplificada
-- Operadores lógicos
SELECT * FROM usuarios WHERE ativo IS NOT NULL;
SELECT * FROM usuarios WHERE NOT ativo; -- Retorna FALSE e NULL? Não! Apenas FALSE
-- CHECK constraint com booleano
CREATE TABLE produtos_ativos (
id INTEGER PRIMARY KEY,
disponivel BOOLEAN NOT NULL DEFAULT TRUE,
CONSTRAINT check_disponivel CHECK (disponivel IS NOT NULL)
);
Conversão implícita e explícita:
-- Conversão implícita em condições
SELECT * FROM usuarios WHERE ativo = 'true'; -- Funciona
-- Conversão explícita
SELECT 't'::BOOLEAN; -- true
SELECT 'yes'::BOOLEAN; -- true
SELECT '1'::BOOLEAN; -- true
SELECT 'f'::BOOLEAN; -- false
SELECT 'no'::BOOLEAN; -- false
SELECT '0'::BOOLEAN; -- false
6. Considerações de armazenamento e performance
O tipo de dado escolhido impacta diretamente no espaço em disco e na performance das consultas:
-- Comparação de tamanhos
SELECT pg_column_size('abc'::CHAR(10)) AS char_size; -- 10 bytes
SELECT pg_column_size('abc'::VARCHAR(10)) AS varchar_size; -- 4 bytes
SELECT pg_column_size('abc'::TEXT) AS text_size; -- 4 bytes
Dicas importantes:
- Evite superdimensionamento: VARCHAR(1000) ocupa mais espaço em índices que VARCHAR(100)
- Prefira tipos específicos: use DATE em vez de TIMESTAMP quando não precisar de hora
- Indexação: índices em tipos numéricos são mais rápidos que em tipos texto
- Overflow: verifique faixas de valores para inteiros e precisão para NUMERIC
- Truncamento: VARCHAR(n) trunca silenciosamente strings maiores que n
-- Exemplo de overflow
CREATE TABLE teste_overflow (
valor SMALLINT
);
INSERT INTO teste_overflow VALUES (40000); -- ERRO: smallint out of range
-- Exemplo de truncamento
CREATE TABLE teste_trunc (
nome VARCHAR(5)
);
INSERT INTO teste_trunc VALUES ('abcdefgh'); -- ERRO: value too long
7. Exemplo prático: criando uma tabela com tipos variados
-- Criação da tabela com tipos variados
CREATE TABLE funcionarios (
id SERIAL PRIMARY KEY,
nome TEXT NOT NULL,
idade INTEGER CHECK (idade >= 18 AND idade <= 120),
salario NUMERIC(12,2) DEFAULT 0.00,
data_cadastro DATE DEFAULT CURRENT_DATE,
ativo BOOLEAN DEFAULT TRUE
);
-- Inserção de dados
INSERT INTO funcionarios (nome, idade, salario, data_cadastro, ativo) VALUES
('Ana Beatriz', 28, 5500.00, '2024-01-15', TRUE),
('Carlos Eduardo', 35, 8200.50, '2024-01-10', TRUE),
('Daniela Santos', 42, 12500.75, '2023-11-20', FALSE);
-- Verificação dos tipos com pg_typeof
SELECT
pg_typeof(nome) AS tipo_nome,
pg_typeof(idade) AS tipo_idade,
pg_typeof(salario) AS tipo_salario,
pg_typeof(data_cadastro) AS tipo_data,
pg_typeof(ativo) AS tipo_ativo
FROM funcionarios LIMIT 1;
-- Consulta demonstrando os tipos em ação
SELECT
nome,
idade,
salario,
data_cadastro,
ativo,
CASE
WHEN ativo THEN 'Sim'
ELSE 'Não'
END AS ativo_texto,
AGE(data_cadastro) AS tempo_cadastro
FROM funcionarios
WHERE ativo = TRUE
ORDER BY salario DESC;
Este exemplo prático demonstra como combinar diferentes tipos de dados em uma única tabela, respeitando constraints e utilizando funções específicas para cada tipo. A escolha adequada dos tipos garante integridade dos dados, performance nas consultas e economia de espaço em disco.
Referências
- Documentação Oficial do PostgreSQL: Tipos de Dados — Referência completa sobre todos os tipos de dados suportados pelo PostgreSQL, incluindo detalhes de armazenamento e sintaxe.
- PostgreSQL Tutorial: Tipos de Dados — Guia prático com exemplos para cada tipo de dado no PostgreSQL.
- PostgreSQL: Booleano — Documentação específica sobre o tipo booleano, incluindo valores aceitos e conversões.
- PostgreSQL: Tipos Numéricos — Detalhamento completo dos tipos numéricos, faixas de valores e precisão.
- PostgreSQL: Tipos de Data/Hora — Documentação oficial sobre tipos de data, hora, timestamp e intervalos.
- PostgreSQL: Funções de String — Lista completa de funções para manipulação de strings no PostgreSQL.
- PostgreSQL: Funções de Data/Hora — Referência de funções para manipulação de datas e horas no PostgreSQL.