PostgreSQL’s JSON data types and functions let you store, query, and transform JSON documents directly in SQL.
PostgreSQL offers two JSON-capable types—json and jsonb. json stores text exactly as inserted. jsonb stores a decomposed binary representation that supports indexing and faster querying. Choose jsonb for most workloads.
Pick json when you only need to validate that text is valid JSON and want the original whitespace.Pick jsonb when you intend to query, index, or update individual keys.
Use CREATE TABLE with a json or jsonb column. Add GIN indexes for jsonb to accelerate key lookups.
Use -> to get JSON objects, ->> to get text, #> to drill into paths, and ? for existence checks.Combine with WHERE and indexes.
For jsonb columns, create a GIN index: CREATE INDEX idx ON Orders USING gin (payload jsonb_path_ops);. Functional indexes accelerate specific keys.
Use jsonb_set or the || operator.Example: UPDATE Customers SET prefs = jsonb_set(prefs,'{theme}','"dark"');.
json_agg and jsonb_build_object let you bundle result sets into JSON documents, ideal for APIs.
SELECT o.id, json_agg(jsonb_build_object('product',p.name,'qty',oi.quantity)) AS items FROM Orders o JOIN OrderItems oi ON oi.order_id=o.id JOIN Products p ON p.id=oi.product_id WHERE o.id=42 GROUP BY o.id;
1. Prefer jsonb with GIN indexes. 2. Keep frequently filtered keys in regular columns. 3. Use CHECK constraints for schema control.
.
Yes, jsonb incurs extra processing on insert, but the performance gain during reads outweighs the cost for most OLTP workloads.
Use CHECK constraints with json_schema or PostgreSQL’s built-in JSON path predicates to validate required keys and types.
A GIN index on the jsonb column with jsonb_path_ops is ideal for existence and containment queries.