1. JSON vs JSONB — Storage & Performance Differences

While `JSON` preserves exact input text formatting (including whitespaces and duplicate key order), `JSONB` converts text into a binary format. Because `JSONB` strips redundant whitespace and indexes object keys internally, it is significantly faster to process and supports GIN indexes.

Creating a Table with JSONB Columns in Postgres
CREATE TABLE user_profiles (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    metadata JSONB NOT NULL
);

-- Insert JSONB Document Payload
INSERT INTO user_profiles (username, metadata) VALUES (
    'alex_dev',
    '{"role": "admin", "skills": ["postgres", "json", "go"], "login_count": 42}'
);
Explanation: JSONB columns accept standard valid JSON strings and convert them to binary representation.

2. Querying JSONB Data with ->, ->>, and @> Operators

PostgreSQL provides specialized operators to extract nested keys and search array items: 1) `->` returns a JSON object/element, 2) `->>` returns extracted text data, and 3) `@>` tests whether a JSONB document contains another JSON structure.

Querying Nested JSONB Attributes & Arrays
-- 1. Extract role as text
SELECT username FROM user_profiles 
WHERE metadata->>'role' = 'admin';

-- 2. Query numerical JSONB fields
SELECT username FROM user_profiles 
WHERE (metadata->>'login_count')::int > 10;

-- 3. Containment Operator (@>) — Check if array contains 'postgres'
SELECT username FROM user_profiles 
WHERE metadata @> '{"skills": ["postgres"]}';
Explanation: The containment operator (@>) evaluates whether the target JSON document contains the specified key-value pattern.

3. Accelerating Queries with GIN Indexes

Without indexes, querying JSONB fields across millions of rows requires sequential full table scans. Creating a Generalized Inverted Index (GIN) on a JSONB column accelerates containment (`@>`) queries dramatically.

Creating a GIN Index on JSONB Column
-- Create GIN Index for fast containment searches
CREATE INDEX idx_user_metadata_gin 
ON user_profiles USING gin (metadata);

-- Explain Query Execution Plan
EXPLAIN ANALYZE 
SELECT * FROM user_profiles 
WHERE metadata @> '{"role": "admin"}';
Explanation: GIN indexes allow PostgreSQL to execute bitmap index scans directly over JSONB keys.