Usando JSON no PostgreSQL
13 Sep 2016No PostgreSQL temos alguns tipos de dados e funções que podem ser muito úteis no nosso dia a dia. Uma delas é o jsonb, existem outros tipos como array, json, hstore.
O PostgreSQL tem dois tipo de json, o json e o jsonb. A principal diferença é que o json armazena uma cópia exata do texto, cada vez que é utilizado a informação, é processado o texto para virar um json, enquanto jsonb é armazenado num formato binário decomposto ou já processado, isso faz com que seja um pouco mais lento a entrada, devido a sobrecarga de conversão adicionado, mas significativamente mais rápida com o processo, uma vez que não é necessário processar a informação toda vez. O jsonb também suporta indexação, que pode ser uma vantagem significativa.
Existem diversas tecnologias e banco de dados especializados em armazenar dados não estruturados. O PostgreSQL evoluiu muito nesse sentido, para atender essa necessidade cada vez mais real nas empresas de software. Se você quer armazenar apenas json em seu banco de dados, talvez o PostgreSQL não seja adequado para a sua necessidade, mas se você precisa armazenar algum dado específico da sua aplicação nesse formato, te encorajo fortemente a utilizar o jsonb. As consultas nesses campos tendem a ter um desempenho considerável. Espero que esses exemplos possam mostrar o quanto o jsonb é funcional e poderoso.
Exemplos:
Verificando se existe um atributo:
postgres=# select '{"a":1, "b":2}'::jsonb ? 'b';
?column?
----------
t
(1 row)
Realizando uma busca:
postgres=# select '{"a":1, "b":2}'::jsonb @> '{"b":2}'::jsonb;
?column?
----------
t
(1 row)
Removendo a posição 1:
postgres=# select '["a", "b"]'::jsonb - 1;
?column?
----------
["a"]
(1 row)
Concatenando:
postgres=# select '["a", "b"]'::jsonb || '["c", "d"]'::jsonb;
?column?
----------------------
["a", "b", "c", "d"]
(1 row)
Removendo um atributo:
postgres=# select '{"a": "b"}'::jsonb - 'a';
?column?
----------
{}
(1 row)
Retornando tuplas a partir de um jsonb:
postgres=# select * from json_each('{"a":"foo", "b":"foo2"}');
key | value
-----+-------
a | "foo"
b | "foo2"
(2 rows)
Retornando um valor de um jsonb:
postgres=# select json_extract_path_text('{"json1":{"node1":0}, "json2":{"node1":666,"node2":"foo"}}','json2', 'node2');
------------------------
foo
(1 row)
Convertendo jsonb para um record:
postgres=# select * from json_to_record('{"column1":1, "column2":[1,2,3],"column3":"foo"}') as x(column1 int, column2 text, column3 text);
column1 | column2 | column3
---------+---------+---------
1 | [1,2,3] | foo
(1 row)