January 17, 2025
Read time: About 6 minutes
Loading... views

Giới thiệu Postgres Jsonb

POSTGRES JSONB

Về cơ bản JSONB là kiểu dữ liệu được phát triễn từ json nhưng khác nhau về cách lưu trữ. JSONB lưu trữ theo kiểu bit nhị phân và giải quyết được hạn chế như : tối ưu quá trình insert và hỗ trợ index cho các trường trong column.

Feature JSON JSONB
Storage Textual representation (verbatim) Binary storage format
Size Typically larger because it retains the whitespace in JSON data Typically smaller
Indexing Full-text search indexes Binary indexes
Performance Slightly slower Generally faster
Query performance Slower due to parsing Faster due to binary storage
Parsing Parse each time Parse once, store in binary format
Data manipulation Simple and easy More complex
Ordering of keys Preserved Not preserved
Duplicate keys Allow duplicate key, the last value is retained Do not allow duplicate keys.
Use cases Storing configuration data, log data, simple JSON documents Storing JSON documents where fast querying and indexing are required

JSONB Example

Tạo bảng product


CREATE TABLE products (

id SERIAL PRIMARY KEY,

data JSONB

);

Insert data vào bảng product:


INSERT INTO products (data)

VALUES

('{

"name": "iPhone 15 Pro",

"category": "Electronics",

"description": "The latest iPhone with advanced features.",

"brand": "Apple",

"price": 999.99,

"attributes": {

"color": "Graphite",

"storage": "256GB",

"display": "6.1-inch Super Retina XDR display",

"processor": "A15 Bionic chip"

},

"tags": \["smartphone", "iOS", "Apple"\]

}'),

('{

"name": "Samsung Galaxy Watch 4",

"category": "Electronics",

"description": "A smartwatch with health tracking and stylish design.",

"brand": "Samsung",

"price": 349.99,

"attributes": {

"color": "Black",

"size": "42mm",

"display": "AMOLED display",

"sensors": \["heart rate monitor", "ECG", "SpO2"\]

},

"tags": \["smartwatch", "wearable", "Samsung"\]

}'),

('{

"name": "Leather Case for iPhone 15 Pro",

"category": "Accessories",

"description": "Premium leather case for iPhone 15 Pro.",

"brand": "Apple",

"price": 69.99,

"attributes": {

"color": "Saddle Brown",

"material": "Genuine leather",

"compatible_devices": \["iPhone 15 Pro", "iPhone 15 Pro Max"\]

},

"tags": \["phone case", "accessory", "Apple"\]

}'),

('{

"name": "Wireless Charging Pad",

"category": "Accessories",

"description": "Fast wireless charger compatible with smartphones and smartwatches.",

"brand": "Anker",

"price": 29.99,

"attributes": {

"color": "White",

"compatible_devices": \["iPhone", "Samsung Galaxy", "Apple Watch", "Samsung Galaxy Watch"\]

},

"tags": \["accessory", "wireless charger"\]

}')

RETURNING \*;

Kết quả:

Ví dụ muốn lấy ra một field trong json:


SELECT

data -> 'name' AS product_name

FROM

products;

Query data -> ‘name’ product_name sẽ lấy ra giá trị của field name trong data và gán vào cột ‘product_name’

Kết quả:

Ví dụ muốn lấy ra một field đồng thời chuyển value đó thành text:


SELECT

data ->> 'name' AS product_name

FROM

products;

kết quả:

Ví dụ filtering với jsonb:

SELECT * FROM products WHERE data ->> ‘brand’ = ‘Apple’;

Ví dụ đếm xem một field nào đó có tồn tại không:

SELECT COUNT(*) FROM products WHERE data ? ‘name’;

Ví dụ chuyển một field array thành các rows:

SELECT

jsonb_array_elements_text(data->’tags’) as tag

FROM products p

WHERE id = 1;

INDEXING

Sự khác biệt lớn nhất giữa json và jsonb đó là jsonb cho phép indexing:

Test index với 10k record

Trước khi index:


EXPLAIN ANALYZE SELECT count(\*) FROM products e WHERE data->>'status' = 'true';

Ta thực hiện đánh index:


CREATE INDEX idx_products_status_btree ON products ((data->>'status'));

Query lại lần nữa:

About this Post

This post is written by haphuthinh, licensed under CC BY-NC 4.0.

Recommended Posts

Bạn thấy khuyến nghị này thế nào?