PostgreSQL: JSON and JSONB data types

Updated: January 6, 2024 By: Guest Contributor Post a comment

Understanding the functionality and utility of the JSON and JSONB data types in PostgreSQL can vastly expand the capabilities of your relational database to operate with semi-structured or unstructured data. Harness these data types to store, query, and manipulate JSON data seamlessly within your PostgreSQL environment.

Introduction

PostgreSQL features support for JSON data types, enabling storage and querying of JSON formatted data. JSONB, introduced in version 9.4, offers additional capabilities such as indexing that allow for efficient query performance. This tutorial guides you through the usage of both JSON and JSONB data types in PostgreSQL.

Understanding JSON and JSONB

JSON (JavaScript Object Notation) is a lightweight data-interchange format that is easy for humans to read and write, and easy for machines to parse and generate. PostgreSQL’s JSON data type allows you to store JSON entries, but just as text without additional intelligence. JSONB (Binary JSON), on the other hand, stores data in a decomposed binary format, providing multiple advantages, including index support and faster access to elements within the JSON structure.

CREATE TABLE example (
   data JSON
);

CREATE TABLE example_b (
   data JSONB
);

Creating Tables with JSON/JSONB Columns

To demonstrate the use of these data types, let’s start by creating tables.

CREATE TABLE customer (
   id serial PRIMARY KEY,
   info JSON NOT NULL
);

CREATE TABLE customer_b (
   id serial PRIMARY KEY,
   info JSONB NOT NULL
);

Here, we’ve established two tables, one for each data type, both equipped to store customer information as JSON or JSONB.

Inserting Data

Inserting data into a JSON or JSONB column is straightforward due to PostgreSQL’s ability to interpret string literals as JSON elements under the appropriate context.

INSERT INTO customer (info)
VALUES ('{"name": "John Doe", "email": "[email protected]"}');

INSERT INTO customer_b (info)
VALUES ('{"name": "Jane Smith", "email": "[email protected]"}'::JSONB);

With JSONB, casting the string using ::JSONB may sometimes be necessary to explicitly convert the input data into the binary format expected by the JSONB column.

Querying JSON/JSONB Data

Retrieving data stored in JSON or JSONB columns is done using familiar SELECT queries. However, PostgreSQL provides operators and functions specifically designed to navigate and extract elements from the JSON data.

-- Get complete JSON object
SELECT info FROM customer WHERE id = 1;

-- Get a specific field from the JSON object
SELECT info->>'name' as name FROM customer WHERE id = 1;

-- Get a JSON object element as text
SELECT info#>>'{address,street}' as street FROM customer_b WHERE id = 2;

Using these operators and functions, you can drill down into the JSON structures to extract just the piece of data you require.

Indexing JSONB Data

One distinct advantage of JSONB over JSON in PostgreSQL is its support for indexing. This can improve performance for specific queries.

-- create GIN index on the JSONB column
CREATE INDEX idxgin ON customer_b USING gin (info);

-- querying with index support
SELECT * FROM customer_b WHERE info @> '{"email": "[email protected]"}';

GIN (Generalized Inverted Indexes) are particularly useful for indexing JSONB objects and can significantly speed up queries when your JSONB data is complex and deep.

JSON/JSONB Operators and Functions

PostgreSQL is equipped with a multitude of operators and functions for JSON and JSONB, which serve everything from simple extraction to complex transformations and manipulation of JSON data.

-- Examples of operators
SELECT 'my_json'->'my_key'; -- get JSON object field as JSON
SELECT 'my_jsonb'->>'my_key'; -- get JSON object field as text

-- Examples of functions
SELECT json_object_keys('my_json'); -- get set of keys in the top level of the JSON object
SELECT jsonb_set('my_json', '{my_key}', '"new_value"', true); -- replace the value of the 'my_key' in 'my_jsonb'

These tools allow you to take full advantage of the flexibility and power of storing JSON in your PostgreSQL database.

Advanced Usage and Performance Considerations

For more advanced applications, JSONB provides functions for sophisticated operations, such as concatenation (|| operator), containment and existence checks (@> and ?| operators, respectively), and more. When working with large amounts of JSONB data, be aware of the impact on performance and consider using appropriate indexes, query plans, and hardware resources.

It’s also advantageous to utilize PostgreSQL’s capabilities for materialized views and partial indexes if you commonly access particular segments of your JSON data, further enhancing query efficiency. Advanced JSONB function examples are beyond the scope of this tutorial but are well-documented in PostgreSQL’s official documentation.

Conclusion

JSON and JSONB data types offer incredible flexibility for developers and DBAs working with dynamic or schema-less data. While JSON serves as a simple storage solution, JSONB shines with its indexing, search performance, and a wealth of functions for robust data manipulation. As mentioned in this tutorial, proper indexing and querying strategies can make a difference in performance. Make the most of PostgreSQL’s JSON capabilities to handle complex data requirements with ease.