Labs ICT
Pro Login

JSONB

JSONB is PostgreSQL's binary JSON data type. It allows you to store, index, and query JSON documents directly in the database. This gives you the flexibility of a document database (like MongoDB) while keeping all the power of SQL and relational features.

Storing JSONB

Creating a table with a JSONB column:

CREATE TABLE events (
  id SERIAL PRIMARY KEY,
  event_type VARCHAR(50),
  data JSONB,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Insert JSON data
INSERT INTO events (event_type, data)
VALUES ('user_action', '{
  "user_id": 123,
  "action": "click",
  "page": "/dashboard",
  "metadata": {
    "browser": "Chrome",
    "os": "Windows"
  }
}');

The data is stored in binary format, which is more efficient than plain text JSON for querying and indexing.

Querying JSONB

PostgreSQL provides operators for navigating and filtering JSON data:

-- Get a specific key
SELECT data->>'user_id' FROM events;

-- Get nested values
SELECT data->'metadata'->>'browser' FROM events;

-- Check if a key exists
SELECT * FROM events WHERE data ? 'user_id';

-- Check for a specific value
SELECT * FROM events WHERE data @> '{"action": "click"}';

-- Filter on nested values
SELECT * FROM events
WHERE data->'metadata'->>'browser' = 'Chrome';

The ->> operator returns text, while -> returns JSONB. Use @> for containment checks which can use GIN indexes.

Modifying JSONB

You can update specific parts of a JSONB document:

-- Add or update a key
UPDATE events
SET data = jsonb_set(data, '{page}', '"/settings"')
WHERE id = 1;

-- Remove a key
UPDATE events
SET data = data - 'metadata'
WHERE id = 1;

-- Merge two JSONB objects
UPDATE events
SET data = data || '{"source": "web"}'
WHERE id = 1;

JSONB Functions

PostgreSQL provides functions for working with JSON:

-- Convert text to JSONB
SELECT '{"name": "Alice"}'::jsonb;

-- Get all keys
SELECT jsonb_object_keys(data) FROM events;

-- Get the type of a value
SELECT jsonb_typeof(data->'user_id') FROM events;

-- Pretty-print JSON
SELECT jsonb_pretty(data) FROM events WHERE id = 1;

Indexing JSONB

For fast queries on JSONB, create a GIN index:

CREATE INDEX idx_events_data ON events USING gin (data);

-- Now containment queries are fast
SELECT * FROM events WHERE data @> '{"action": "click"}';

-- For specific key queries, create a btree index on the expression
CREATE INDEX idx_events_user_id ON events ((data->>'user_id'));

SELECT * FROM events WHERE data->>'user_id' = '123';

When to Use JSONB

JSONB is great when you:

  • Have variable or evolving data structures
  • Store configuration, metadata, or semi-structured data
  • Need to query inside JSON documents efficiently
  • Want document-database flexibility with SQL power

Avoid JSONB when you have a fixed, well-defined schema. Relational columns are faster and more efficient for structured data.