No PostgreSQL, muita gente desenvolvedora fica na dúvida: qual estrutura de dados usar pra guardar informação? Usar arrays (ARRAY) pra uma estrutura mais simples? Ou colunas de texto (TEXT) pra strings? Ou talvez HSTORE pra guardar pares "chave-valor"? E claro, sempre rola a pergunta: quando é melhor usar JSON ou JSONB?
Pra te ajudar a sacar isso, vamos falar das vantagens e desvantagens de cada abordagem, além de mostrar exemplos de uso.
Quando usar arrays (ARRAY) e quando JSONB?
Arrays (ARRAY) são ótimos pra dados que são conjuntos homogêneos de valores. Tipo, se tu tem uma lista de notas de estudantes ou tags pra um registro, array cai perfeito.
Exemplo de array:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name TEXT,
grades INTEGER[] -- array de notas
);
INSERT INTO students (name, grades)
VALUES ('Alice', ARRAY[90, 85, 88]),
('Bob', ARRAY[70, 75, 78]);
Por outro lado, JSONB serve pra estruturas mais complexas e aninhadas. Se tu quer guardar dados extras pra cada registro, tipo uma descrição pra cada nota, JSONB é o caminho.
Exemplo de JSONB:
CREATE TABLE students_json (
id SERIAL PRIMARY KEY,
name TEXT,
grades JSONB -- objeto com dados das notas
);
INSERT INTO students_json (name, grades)
VALUES ('Alice', '{"Math": 90, "Science": 85, "English": 88}'),
('Bob', '{"Math": 70, "Science": 75, "English": 78}');
Diferencinhas principais
| Critério | Arrays (ARRAY) |
JSONB |
|---|---|---|
| Estrutura | Dados homogêneos de um tipo só | Estruturas de dados complexas e aninhadas |
| Acesso aos dados | Pelo índice: grades[1] |
Pela chave: grades->'Math' |
| Suporte a índices | Só GIN ou BTREE pro array inteiro |
Índices GIN e BTREE de boa pras chaves |
| Quando usar | Listas simples de dados (tags, notas, ids) | Objetos complexos com chaves e valores |
Exemplos de conversão de array pra JSONB e vice-versa
Bora ver como dá pra converter dados entre arrays e JSONB:
Array → JSONB
SELECT to_jsonb(grades) AS grades_jsonb
FROM students;
-- Resultado:
-- [{"90","85","88"}]
JSONB → Array
SELECT array_agg(value::INTEGER) AS grades_array
FROM jsonb_array_elements_text('["90", "85", "88"]');
-- Resultado:
-- {90,85,88}
Comparando JSONB e dados de texto (TEXT)
Colunas de texto são ideais se tu só precisa guardar strings ou dados não estruturados pequenos. Se tua tarefa é buscar por correspondência de string, tipo no nome de um produto ou descrição, TEXT é a escolha.
CREATE TABLE books (
id SERIAL PRIMARY KEY,
title TEXT,
description TEXT
);
INSERT INTO books (title, description)
VALUES ('SQL Basics', 'Uma introdução concisa ao SQL'),
('Advanced PostgreSQL', 'Um guia aprofundado de performance no PostgreSQL');
Quando é melhor usar JSONB?
Se tua string vira uma informação com estrutura aninhada (tipo uma descrição com categoria dentro e lista de tags), melhor ir de JSONB.
CREATE TABLE books_json (
id SERIAL PRIMARY KEY,
info JSONB
);
INSERT INTO books_json (info)
VALUES ('{"title": "SQL Basics", "tags": ["iniciante", "banco de dados"]}'),
('{"title": "Advanced PostgreSQL", "tags": ["performance", "otimização"]}');
Diferencinhas principais
| Critério | Texto (TEXT) |
JSONB |
|---|---|---|
| Estrutura | Dados não estruturados | Dados estruturados e aninhados |
| Busca | Busca full-text | Busca por chaves, valores, estrutura aninhada |
| Alteração de dados | Só substituição total | Alteração de chaves específicas |
| Quando usar | Strings de texto simples | Dados complexos no formato chave-valor |
Comparando JSONB e HSTORE
HSTORE é tipo o irmão mais velho do JSONB, que deixa guardar pares "chave-valor". Por exemplo, se tua estrutura de dados é simples (não precisa de aninhamento nem arrays), HSTORE é mais leve e rápido.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
attributes HSTORE
);
INSERT INTO products (attributes)
VALUES ('"cor"=>"vermelho", "tamanho"=>"M"'),
('"cor"=>"azul", "tamanho"=>"L"');
Por que JSONB substituiu HSTORE?
Apesar do HSTORE ser prático pra pares "chave-valor", ele não suporta aninhamento nem arrays, o que faz o JSONB ser bem mais versátil. Se tu já passou da fase dos objetos simples, JSONB é o próximo passo natural.
Diferencinhas principais
| Critério | HSTORE | JSONB |
|---|---|---|
| Estrutura | Pares "chave-valor", sem aninhamento | Estruturas aninhadas completas |
| Suporte a array | Não | Sim |
| Busca | Só por chave | Por chaves, valores, estrutura aninhada |
| Quando usar | Pares chave-valor simples | Estruturas de dados complexas |
Como escolher o tipo de dado certo?
Se tu tem:
- Estrutura simples — listas ou dados homogêneos, usa arrays (
ARRAY). - Strings ou descrições simples, usa colunas de texto (
TEXT). - Pares "chave-valor" sem aninhamento, vai de
HSTORE. - Objetos aninhados e arrays, estrutura de dados complexa — tu precisa de JSONB.
Exemplos de conversão entre formatos
TEXT → JSONB
SELECT to_jsonb('Exemplo simples de texto') AS jsonb_form;
-- Resultado: "Exemplo simples de texto"
JSONB → TEXT
SELECT info::TEXT AS text_form
FROM books_json;
-- Resultado: {"title": "SQL Basics", "tags": ["iniciante", "banco de dados"]}
HSTORE → JSONB
SELECT hstore_to_jsonb(attributes) AS jsonb_form
FROM products;
-- Resultado: {"cor": "vermelho", "tamanho": "M"}
JSONB → HSTORE
SELECT jsonb_to_hstore('{"cor": "vermelho", "tamanho": "M"}') AS hstore_form;
-- Resultado: "cor"=>"vermelho", "tamanho"=>"M"
No que ficar ligado?
Se tu precisa de máxima flexibilidade e suporte pra estruturas complexas, escolhe JSONB. Mas se tua tarefa é lidar com estruturas simples, tipo arrays, texto ou pares "chave-valor", usa os tipos de dados certos (ARRAY, TEXT, HSTORE).
Lembra que escolher a estrutura de dados certa vai te poupar dor de cabeça depois e ainda turbina a performance das tuas queries.
GO TO FULL VERSION