CodeGym /Cursos /SQL SELF /Erros comuns ao trabalhar com dados JSON e como evitá-los...

Erros comuns ao trabalhar com dados JSON e como evitá-los

SQL SELF
Nível 34 , Lição 4
Disponível

Mexer com dados JSON no PostgreSQL é uma baita ferramenta, mas como qualquer ferramenta, tem que usar com cuidado. Até um errinho bobo pode transformar sua query num quebra-cabeça. Hoje vamos focar de novo nos erros clássicos que rolam quando a galera trabalha com JSON e JSONB no PostgreSQL, e claro, como evitar essas tretas.

Problema 1: usar JSON em vez de JSONB

Muita gente que tá começando acaba usando o tipo JSON, achando que é a melhor escolha pra guardar dados em formato JSON. Só que o JSON no PostgreSQL salva tudo como texto, e isso pode deixar as buscas e filtros bem mais lentos.

Exemplo de erro:

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    details JSON
);

INSERT INTO products (details) VALUES ('{"nome": "Laptop", "preço": 1000}');

INSERT INTO products (details) VALUES ('{"nome": "Laptop", "preço": 1000}');

Se você tentar filtrar pelo campo (preço), vai perceber que fica bem mais devagar do que usando JSONB.

Como resolver: usa JSONB se você pretende filtrar ou acessar os dados direto.

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    details JSONB
);

Problema 2: falta de índices pra JSONB

JSONB é super poderoso, mas sem índice, quando a query é mais pesada, a performance pode cair feio.

Exemplo de erro: imagina que você tem uma tabela com a coluna details, onde guarda um monte de objetos JSON:

SELECT * FROM products WHERE details->>'nome' = 'Laptop';

Se os dados não tiverem índice, o servidor vai ter que varrer a tabela inteira (full table scan), gastando muito mais tempo.

Como resolver: cria um índice GIN pra agilizar a busca pelos campos:

CREATE INDEX idx_details_nome ON products USING gin (details jsonb_path_ops);

Problema 3: erros ao extrair dados aninhados

Pegar dados de objetos ou arrays dentro do JSON pode confundir, principalmente se você não manja a diferença entre os operadores -> e ->>.

Exemplo de erro:

SELECT details->'preço' FROM products;

Essa query vai retornar o valor em formato JSON, não como string ("1000" em vez de 1000). Se você quer só o valor, tem que usar ->>:

SELECT details->>'preço' FROM products;

Problema 4: uso errado dos operadores

Talvez você já viu o operador @> e pensou: "Pô, parece massa, vou usar sempre!" Mas se não sacar como ele funciona, pode ter resultado estranho.

Exemplo de erro:

SELECT * FROM products WHERE details @> '{"preço": 1000}';

Essa query só funciona se preço for um número no JSON. Se o valor estiver salvo como string "1000", não vai retornar nada.

Como resolver: fica ligado nos tipos de dados dentro do JSON:

SELECT * FROM products WHERE details->>'preço' = '1000';

Problema 5: Objetos JSON muito grandes

Guardar objetos JSON enormes sem otimizar pode deixar as queries bem lentas. E pior: pra ler ou mudar até um pedacinho do JSONB, o PostgreSQL tem que processar o objeto inteiro.

Como resolver: se tem campos que você usa toda hora, coloca eles em colunas separadas na tabela. Tipo assim:

ALTER TABLE products ADD COLUMN preço NUMERIC;
UPDATE products SET preço = (details->>'preço')::NUMERIC;

Agora dá pra filtrar e ordenar rapidinho, sem precisar ficar quebrando o JSONB toda vez.

Problema 6: reconstrução total do objeto ao atualizar

Quando você usa funções tipo jsonb_set() ou jsonb_insert(), o PostgreSQL cria um objeto JSONB novinho, e isso pode pesar na performance.

Como resolver: tenta atualizar o JSONB o mínimo possível. Por exemplo, em vez de ficar atualizando toda hora, junta tudo numa query só:

UPDATE products
SET details = jsonb_set(details, '{preço}', '1500'::jsonb);

Problema 7: não entender a estrutura do array

Arrays em JSONB também merecem atenção. Imagina que você tem um array assim:

{
    "tags": ["eletrônicos", "laptop", "promoção"]
}

Você quer ver se tem a tag "laptop". Se usar o operador @> errado, pode não achar nada, porque ele espera um array, não uma string.

Exemplo de erro:

SELECT * FROM products WHERE details->'tags' @> '"laptop"';

Como resolver: Usa o formato certo no operador @>:

SELECT * FROM products WHERE details->'tags' @> '["laptop"]';

Dicas pra evitar erros

Pra não cair em várias ciladas quando mexer com JSONB, segue essas dicas:

Escolhe o tipo de dado certo. Se você trabalha com muitos dados e faz filtro direto, sempre vai de JSONB em vez de JSON.

Indexa os dados. Se as queries sempre buscam por certos campos, cria um índice maneiro (tipo GIN).

Confere os dados antes de inserir. Usa funções de validação pra checar a estrutura dos dados:

DO $$
BEGIN
    IF jsonb_typeof('{"preço": 1000}'::jsonb->'preço') IS DISTINCT FROM 'number' THEN
        RAISE EXCEPTION 'Preço tem que ser um número';
    END IF;
END $$;

Otimiza a estrutura dos dados. Se tem campos que aparecem mais, coloca eles em colunas separadas na tabela.

Estuda os operadores e funções. Lê com atenção a documentação oficial do PostgreSQL pra sacar bem a diferença entre ->, ->>, @>, ?| e outras funções.

JSON e JSONB podem ser seus parceiros pra lidar com dados flexíveis e complexos. O segredo é escolher bem as ferramentas e fugir dos erros comuns, assim seu código fica rápido e fácil de manter.

1
Pesquisa/teste
Atualizando dados em objetos JSON, nível 34, lição 4
Indisponível
Atualizando dados em objetos JSON
Atualizando dados em objetos JSON
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION