title: "SQLite for beginners: JSON"
Youtube_Thumbnail: https://img.youtube.com/vi/vBab2KvB5EI/hqdefault.jpg
sources: https://www.youtube.com/watch?v=vBab2KvB5EI
media_link: https://www.youtube.com/watch?v=vBab2KvB5EI
contentPublished: 2023-01-05
noteCreated: 2025-07-12
description: Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
tags:
- clippings
- video
takeaways:
subjects:
Status: ✅ Read
publish: true
Youtube_Duration: 6:43Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube.
SQLite has added support for handling JSON inside the database in recent years. While SQLite doesn't have as much JSON support as alternatives like PostgreSQL, it does allow you to store JSON in text columns and provides JSON-related functions and operators for manipulation and querying.
Important caveat: JSON should be used sparingly in databases because:
Most APIs return JSON, so it makes sense to log the JSON response as returned from the API.
JSON is useful for storing attributes that are used infrequently. For example, in a kitchen cabinet sales system where each order is highly customized with unique build attributes.
The example uses an order_lines table with kitchen cabinet sales information. Each row stores a cabinet with its unique set of build attributes in an attributes column (text column storing JSON).
Sample data structure:
| id | product | quantity | attributes |
|---|---|---|---|
| 1 | Cabinet | 2 | {"depth": 24, "width": 36, "height": 84, "hardware": "brass"} |
CREATE TABLE order_lines (
id integer PRIMARY KEY,
-- ...
) ;
In the example, every row has depth, width, and height attributes, which aren't sparsely used. Rule of thumb: Only store JSON attributes if they're sparsely used.
To query for total quantity of 24-inch deep cabinets:
SELECT SUM(quantity)
FROM order_lines
WHERE JSON_EXTRACT(attributes, '$.depth') = 24;
SELECT SUM(quantity)
FROM order_lines
WHERE attributes ->> '$.depth' = 24;
Both queries take 7-8 seconds to execute.
Since depth, width, and height are used frequently, they should be moved to their own columns:
ALTER TABLE order_lines ADD COLUMN depth INTEGER;
ALTER TABLE order_lines ADD COLUMN width INTEGER;
ALTER TABLE order_lines ADD COLUMN height INTEGER;
UPDATE order_lines
SET depth = JSON_EXTRACT(attributes, '$.depth');
UPDATE order_lines
SET width = JSON_EXTRACT(attributes, '$.width');
UPDATE order_lines
SET height = JSON_EXTRACT(attributes, '$.height');
UPDATE order_lines
SET attributes = JSON_REMOVE(attributes, '$.depth', '$.width', '$.height');
After moving dimensions to dedicated columns, the same query now takes 1-2 seconds instead of 7-8 seconds:
SELECT SUM(quantity)
FROM order_lines
WHERE depth = 24;
Why it's faster:
For JSON attributes that must remain in JSON format, you can create indexes on JSON expressions:
CREATE INDEX idx_hardware
ON order_lines(JSON_EXTRACT(attributes, '$.hardware'));
Query example:
SELECT COUNT(*)
FROM order_lines
WHERE JSON_EXTRACT(attributes, '$.hardware') = 'brass';
This greatly improves performance for JSON-based queries.