Escolher o tipo de dado é tipo escolher a ferramenta certa pra um trampo. Você não vai usar uma chave de fenda pra martelar um prego (espero, né). No banco de dados é a mesma coisa: o tipo de dado certo faz muita diferença na performance, economia de memória e facilidade pra mexer nos dados. Por exemplo, se a gente guarda dinheiro no formato REAL, pode dar ruim na precisão, e usar TEXT no lugar de VARCHAR pra strings curtas só vai gastar mais memória à toa.
Quando for escolher o tipo de dado, pensa em alguns pontos:
Natureza dos dados
Descobre de que categoria são os dados: números, strings, valores booleanos, datas ou algo mais complexo, tipo estruturas JSON.
Volume de dados
Quanto de dado você vai guardar? Por exemplo, pra textos de até 50 caracteres, melhor usar VARCHAR(50) do que TEXT.
Precisão e faixa
Precisa de precisão alta (tipo pra cálculos financeiros)? Quer limitar o intervalo de valores?
Frequência e tipo das queries
Com que frequência você vai acessar esses dados? Lembra que tipos mais complexos, tipo JSONB, exigem mais recurso pra processar.
Exemplos de escolha de tipos de dados
Dados diferentes, tarefas diferentes. Às vezes a precisão é tudo, às vezes só precisa caber tudo. Olha aí embaixo exemplos de como escolher o tipo de dado certo pra cada situação.
Dados financeiros
Quando o papo é guardar grana, igual na contabilidade, errar não pode. O melhor é usar o tipo NUMERIC, que garante precisão alta. Por exemplo, queremos uma tabela com essas colunas:
| Nome da coluna | Tipo de dado | Comentário |
|---|---|---|
| id | SERIAL | Chave primária |
| amount | NUMERIC(10, 2) | Dez dígitos, sendo dois depois da vírgula |
| currency_code | CHAR(3) | Código ISO da moeda, tipo "USD", "EUR" |
| transaction_date | TIMESTAMP | Hora da transação, padrão é hora atual |
Por que não REAL? Porque números float podem perder precisão, e isso é crítico pra dinheiro.
Dados de texto
Se você vai guardar nomes de usuário, endereços ou qualquer outra string, sempre define o tamanho máximo quando der. Tipo, VARCHAR(50) em vez de TEXT. Isso evita erro e economiza memória.
| Nome da coluna | Tipo de dado | Comentário |
|---|---|---|
| id | SERIAL | Chave primária |
| username | VARCHAR(50) | Login do usuário, único e obrigatório |
| VARCHAR(255) | ||
| bio | TEXT | Bio, pode ser texto grandão |
Se o tamanho da string é fixo (tipo código de país com dois dígitos), usa CHAR:
| Nome da coluna | Tipo de dado | Comentário |
|---|---|---|
| code | CHAR(2) | Código ISO do país (tipo "US"), chave primária |
| name | VARCHAR(100) | Nome do país, obrigatório |
Dados de timestamp
Pra guardar hora de eventos ou agendas, normalmente TIMESTAMP resolve, porque tem data e hora junto.
| Nome da coluna | Tipo de dado | Comentário |
|---|---|---|
| id | SERIAL | Chave primária |
| event_name | VARCHAR(100) | Nome do evento |
| start_time | TIMESTAMP | Hora de início do evento, obrigatório |
| end_time | TIMESTAMP | Hora de fim do evento, obrigatório |
Se só precisa da hora sem data, usa TIME, e se só precisa da data sem hora — DATE.
Identificadores únicos
Quando precisa criar identificadores únicos no mundo todo, usa UUID. Por exemplo, pra gerar um id único de transação:
| Nome da coluna | Tipo de dado | Comentário |
|---|---|---|
| request_id | UUID | Identificador único da requisição, gerado por padrão com gen_random_uuid() |
| endpoint | VARCHAR(255) | Endereço do endpoint da API chamada |
| timestamp | TIMESTAMP | Hora da requisição, padrão é hora atual |
JSONB: estruturas complexas
Quando precisa guardar dados que mudam de estrutura ou são complexos, tipo configs de usuário ou metadados, usa JSONB.
| Nome da coluna | Tipo de dado | Comentário |
|---|---|---|
| user_id | SERIAL | Chave primária (ID do usuário) |
| preferences | JSONB | Configurações do usuário em formato JSON |
Trabalhar com JSONB é de boa, mas lembra que pode ficar mais lento se tiver muita inserção/atualização.
Arrays
Arrays são bons quando precisa guardar listas de dados do mesmo tipo. Tipo uma lista de tags:
| Nome da coluna | Tipo de dado | Comentário |
|---|---|---|
| id | SERIAL | Chave primária |
| title | VARCHAR(255) | Título do artigo |
| tags | TEXT[] | Array de tags |
Resumo dos tipos de dados por tarefa
| Tipo de tarefa | Tipo de dado recomendado | Exemplo |
|---|---|---|
| Identificador de registro | SERIAL, BIGSERIAL, UUID |
id SERIAL PRIMARY KEY |
| Quantidade, números inteiros | INTEGER, BIGINT |
quantity INTEGER |
| Cálculos financeiros | NUMERIC |
price NUMERIC(10, 2) |
| Armazenamento de strings | VARCHAR(n), TEXT |
username VARCHAR(50) |
| Strings curtas e fixas | CHAR(n) |
status CHAR(1) |
| Datas e hora | DATE, TIME, TIMESTAMP |
created_at TIMESTAMP DEFAULT NOW() |
| Identificadores únicos | UUID |
id UUID PRIMARY KEY DEFAULT gen_random_uuid() |
| Estruturas complexas (JSON) | JSONB |
metadata JSONB |
| Listas de valores | ARRAY |
tags TEXT[] |
| Valor booleano | BOOLEAN |
is_active BOOLEAN |
Você provavelmente já viu todos esses tipos menos o SERIAL. O lance é que SERIAL é basicamente um INTEGER usado como id das linhas nas tabelas.
Ele aumenta automaticamente em 1 quando você adiciona uma linha nova na tabela. Então, se você colocar 10 linhas, a primeira vai ter id 1, a segunda 2 e por aí vai. Mais sobre isso você vai ver na próxima aula :)
GO TO FULL VERSION