JSON ба JSONB өгөгдөл
Зарим өгөгдлийн бүтэц урьдчилан тодорхойгүй байдаг — жишээлбэл бүтээгдэхүүний нэмэлт шинж чанар, хэрэглэгчийн тохиргоо, гадаад API-аас ирсэн өгөгдөл. Эдгээрт тусдаа хүснэгт үүсгэхийн оронд PostgreSQL-н JSON эсвэл JSONB төрлийг ашиглаж болно. Энэ нь SQL-н хатуу бүтэц болон MongoDB-г хэрэглэсэн мэт уян хатан байдлыг хослуулдаг.
JSON vs JSONB — ялгаа
| | JSON | JSONB | |---|---|---| | Хадгалалт | Текст хэлбэрээр, дарааллыг хадгална | Хоёртын форматаар, задалсан | | Индекс | ❌ боломжгүй | ✅ GIN индекс | | Хурд (унших) | Удаан (дахин задлах) | Хурдан | | Хурд (бичих) | Хурдан | Арай удаан | | Давхардсан түлхүүр | Хадгална | Сүүлчийнхийг авна |
Ихэнх тохиолдолд JSONB сонгох нь зөв — индекс тавьж болдог, хурдан уншдаг.
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
price NUMERIC NOT NULL,
attributes JSONB -- уян хатан шинж чанарууд
);
INSERT INTO products (name, price, attributes) VALUES
('Утас Samsung', 850000, '{"өнгө": "хар", "RAM": 8, "хадгалалт": 128, "5G": true}'),
('Утас iPhone', 1200000, '{"өнгө": "цагаан", "RAM": 6, "хадгалалт": 256, "5G": true}'),
('Чихэвч Sony', 95000, '{"өнгө": "хар", "утасгүй": true, "цагийн_хугацаа": 30}'),
('Гар чийдэн', 12000, '{"гэрэлтэх_хугацаа": 8, "батарей": "AAA"}');
JSON өгөгдлийг унших
PostgreSQL нь JSON утга унших хэд хэдэн оператор санал болгодог:
-- -> оператор: JSON утга буцаана (JSON хэлбэрээр)
SELECT name, attributes -> 'өнгө' AS өнгө
FROM products;
-- Үр дүн: "хар", "цагаан" (хашилттай)
-- ->> оператор: TEXT утга буцаана
SELECT name, attributes ->> 'өнгө' AS өнгө
FROM products;
-- Үр дүн: хар, цагаан (хашилтгүй)
-- Тоон утгыг буцаах
SELECT name, (attributes ->> 'RAM')::INT AS ram_gb
FROM products
WHERE attributes ? 'RAM'
ORDER BY ram_gb DESC;
-- WHERE дотор JSON талбараар шүүх
SELECT name, price
FROM products
WHERE attributes ->> 'өнгө' = 'хар';
-- Тодорхой түлхүүр байгаа эсэхийг шалгах (? оператор)
SELECT name FROM products WHERE attributes ? '5G';
-- Олон түлхүүр байгаа эсэхийг шалгах (?& оператор)
SELECT name FROM products WHERE attributes ?& ARRAY['5G', 'RAM'];
JSON өгөгдлийг шинэчлэх
jsonb_set() функцоор JSONB утгыг шинэчилж болно:
-- Нэг талбарыг шинэчлэх
UPDATE products
SET attributes = jsonb_set(attributes, '{өнгө}', '"улаан"')
WHERE name = 'Гар чийдэн';
-- Шинэ талбар нэмэх
UPDATE products
SET attributes = attributes || '{"баталгаат_хугацаа": 12}'
WHERE name = 'Чихэвч Sony';
-- Талбар устгах (- оператор)
UPDATE products
SET attributes = attributes - 'батарей'
WHERE name = 'Гар чийдэн';
GIN индекс — JSONB хайлтыг хурдасгах
JSONB талбарт GIN индекс тавьснаар их хэмжээний өгөгдөлд хайлт хурдасна:
-- Бүх JSONB түлхүүр болон утгад GIN индекс
CREATE INDEX idx_products_attributes
ON products USING GIN (attributes);
-- Одоо энэ хайлт маш хурдан болно
SELECT name FROM products
WHERE attributes @> '{"өнгө": "хар"}';
-- @> оператор: зүүн тал нь баруун талыг "агуулж байна уу?" гэдгийг шалгана
JSON хэлбэртэй гаралт
Хүснэгтийн мөрийг JSON болгон буцаах:
-- Мөрийг JSON болгох
SELECT ROW_TO_JSON(p) FROM products p WHERE id = 1;
-- Бүх мөрийг JSON массив болгох
SELECT JSON_AGG(
JSON_BUILD_OBJECT(
'нэр', name,
'үнэ', price,
'өнгө', attributes ->> 'өнгө'
)
) AS бараанууд
FROM products
WHERE attributes ? 'өнгө';
Дараагийн хичээлд:
PostgreSQL-д нэг талбарт олон утга хадгалах массив өгөгдлийн төрлийг сурна — тэмдэгт, тоо, огноо бүхий массивыг үүсгэж, хайж, шинэчлэх аргуудыг авч үзнэ.