- 26
- March
If you've worked with APIs, ERP systems, or even configuration files, you've likely encountered JSON. But when using PostgreSQL, you'll find two similar-sounding data types: JSON and JSONB. This article explains what each is, how they differ, when to use which, and which PostgreSQL versions support them.
What Is JSON?
JSON (JavaScript Object Notation) is a lightweight, text-based data format for storing and exchanging data. It's human-readable and machine-parseable, making it the de facto "universal language" for data interchange between systems.
JSON Example
{
"employee_id": "EMP-001",
"name": "John Smith",
"department": "Accounting",
"skills": ["Excel", "SAP", "ERP"],
"active": true
}
JSON uses a key-value pair structure that can be nested to multiple levels. It supports 6 basic data types:
| Data Type | Example | Description |
|---|---|---|
| String | "John" |
Text enclosed in double quotes |
| Number | 42, 3.14 |
Integer or decimal numbers |
| Boolean | true, false |
True/false values |
| Array | ["a", "b", "c"] |
Ordered list of values |
| Object | {"key": "value"} |
Nested data structure |
| Null | null |
Represents no value |
What Is JSONB?
JSONB (JSON Binary) stores JSON data in a decomposed binary format — the same data as JSON, but stored in a way that enables much faster searching and processing.
Simple analogy: JSON is like storing a document as plain text — readable but slow to search. JSONB is like storing it in a digital filing system with indexes — instant lookup.
How Do JSON and JSONB Differ?
Here's the most important comparison table:
| Feature | JSON | JSONB |
|---|---|---|
| Storage format | Stored as-is (text) | Converted to binary before storing |
| Write speed | Faster (no conversion) | Slightly slower (must parse) |
| Read/query speed | Slow (must parse every time) | Very fast (direct key access) |
| Index support | Not supported | GIN Index supported |
| Key ordering | Preserves insertion order | Does not preserve order (re-sorted) |
| Duplicate keys | Keeps all duplicates | Keeps only the last value |
| Whitespace | Preserved as-is | Stripped of insignificant whitespace |
| Storage size | Matches text size | Slightly larger (metadata overhead) |
| Special operators | Limited | Full set (@>, ?, ?|, ?&) |
What Are JSON and JSONB Used For?
In Saeree ERP and enterprise information systems, JSON/JSONB is used extensively:
| Use Case | Example | Recommended |
|---|---|---|
| Config/Settings | Approval workflows, user permissions, report templates | JSONB |
| API Responses | Data from government systems, tax services, banks | JSONB |
| Audit Logs | Before/after snapshots of modified records | JSONB |
| Custom Fields | Organization-specific fields that vary per client | JSONB |
| Raw Logs | Raw data that must preserve its original format | JSON |
Simple rule: If you need to query, filter, or search inside the data → use JSONB. If you just store it and read it back as a whole → JSON is fine.
Real SQL Examples on PostgreSQL
1. Create a Table with a JSONB Column
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
profile JSONB
);
-- Insert data
INSERT INTO employees (name, profile) VALUES
('John Smith', '{
"department": "Accounting",
"position": "Accountant",
"skills": ["Excel", "SAP", "ERP"],
"salary": 35000,
"active": true
}'),
('Jane Doe', '{
"department": "Procurement",
"position": "Procurement Officer",
"skills": ["Inventory", "ERP"],
"salary": 30000,
"active": true
}');
2. Extract Values from JSONB
-- Get department (returns JSON value)
SELECT name, profile->'department' AS dept
FROM employees;
-- Get department as plain text (no quotes)
SELECT name, profile->>'department' AS dept
FROM employees;
Key Operators:
->Extract as JSON (chainable)->>Extract as text#>Extract by path as JSON#>>Extract by path as text@>Contains (checks if JSONB contains given key-value)?Key exists (checks if a key is present)
3. Search Inside JSONB
-- Find employees in the Accounting department
SELECT name FROM employees
WHERE profile->>'department' = 'Accounting';
-- Find employees with the "ERP" skill
SELECT name FROM employees
WHERE profile @> '{"skills": ["ERP"]}';
-- Find employees with salary above 32,000
SELECT name, (profile->>'salary')::int AS salary
FROM employees
WHERE (profile->>'salary')::int > 32000;
4. Update Values in JSONB
-- Change department
UPDATE employees
SET profile = jsonb_set(profile, '{department}', '"Finance"')
WHERE name = 'John Smith';
-- Add a new key
UPDATE employees
SET profile = profile || '{"phone": "02-347-7730"}'
WHERE name = 'John Smith';
-- Remove a key
UPDATE employees
SET profile = profile - 'phone'
WHERE name = 'John Smith';
5. Create Indexes for JSONB
-- GIN Index — fast search across all keys
CREATE INDEX idx_profile ON employees USING GIN (profile);
-- GIN with jsonb_path_ops — faster but only supports @>
CREATE INDEX idx_profile_path ON employees
USING GIN (profile jsonb_path_ops);
-- B-Tree index on a specific key — fastest for frequently queried keys
CREATE INDEX idx_department ON employees
((profile->>'department'));
Which PostgreSQL Versions Support JSON/JSONB?
PostgreSQL has been adding JSON capabilities since version 9.2, improving with every release:
| Version | Year | JSON/JSONB Capabilities Added |
|---|---|---|
| 9.2 | 2012 | First JSON data type — basic storage and validation |
| 9.3 | 2013 | Added ->, ->> operators and json_each(), json_array_elements() |
| 9.4 | 2014 | Introduced JSONB — binary storage, GIN Index, operators @>, ?, || |
| 9.5 | 2016 | Added jsonb_set(), || for merge, - operator to remove keys |
| 9.6 | 2016 | Added jsonb_insert(), jsonb_pretty() |
| 12 | 2019 | Added SQL/JSON Path Language — query with jsonpath e.g., $.skills[*] |
| 14 | 2021 | Added Subscripting — access JSONB with profile['department'] instead of -> |
| 16 | 2023 | Added SQL/JSON Constructors per SQL:2016 standard — JSON_ARRAY(), JSON_OBJECT() |
| 17 | 2024 | Added JSON_TABLE() — converts JSON directly into relational table rows |
Recommendation: For full JSONB capabilities, use PostgreSQL 12 or later for SQL/JSON Path Language support. Saeree ERP has used PostgreSQL for over 20 years and recommends version 14+ for new installations.
Comparison with Other Databases
PostgreSQL isn't the only database that supports JSON — but the depth of support varies significantly:
| Database | JSON Support | Indexing | Notes |
|---|---|---|---|
| PostgreSQL | JSON + JSONB | GIN, GiST, B-Tree | Most comprehensive + SQL/JSON Path |
| MySQL 8.0+ | JSON (Binary) | Multi-Valued Index | Good support but fewer operators |
| Oracle 21c+ | JSON + JSON Duality View | Search Index | Excellent but expensive licensing |
| SQL Server | NVARCHAR + JSON Functions | Computed Column | No native JSON type until 2025 Preview |
| MongoDB | BSON (Native) | Full | Document DB — not relational |
Important Caveats When Using JSONB
While JSONB is powerful, it shouldn't be used everywhere — understand its limitations:
- Don't replace regular columns — If data has a clear, fixed structure (name, email, date), use proper typed columns for better data validation
- Watch the data size — Very large JSONB values can slow down backup operations
- No foreign keys — You cannot create FK constraints referencing keys inside JSONB
- Per-key updates — Modifying JSONB actually rewrites the entire column value (not an in-place update)
JSONB in PostgreSQL gives us the best of both worlds — the flexibility of NoSQL combined with the reliability of a relational database. In Saeree ERP, we use JSONB for workflow configuration, audit logs, and custom fields, allowing the system to stay flexible without altering table structures.
— Paitoon Butri, Server Security Specialist, Grand Linux Solution
Summary — JSON vs JSONB: Which Should You Choose?
| Scenario | Choose | Reason |
|---|---|---|
| Need to query/search inside the data | JSONB | Index support, full operators, fast queries |
| Storing config, settings, metadata | JSONB | Easy per-key modification |
| Archiving logs that must preserve format | JSON | Preserves key order and formatting |
| Write-heavy, rarely read | JSON | Faster writes (no parsing overhead) |
| Unsure / most use cases | JSONB | Default choice — flexible and fast for all query scenarios |
If you're interested in an ERP system that uses PostgreSQL as its core database and takes full advantage of JSONB, schedule a demo or contact the Saeree ERP consulting team today.
