Mundarija (38)
- Bu darsda
- 1. Nega bu kerak?
- 2. Sozlamalar ustuni
- 2.1 Kanon fayli
- 2.2 Namuna ma'lumot
- 3. Ichiga kirish: ->, ->>, #>, #>>
- 3.1 To'rt operator
- 3.2 Tur tuzog'i: ->> doim matn
- 4. Qidirish: @> va kalit operatorlari
- 4.1 @> — "shu bo'lak ichida bormi"
- 4.2 ?, ?|, ?& — kalit bormi
- 5. O'zgartirish: jsonb_set, ||, -, #-
- 5.1 jsonb_set — bitta qiymatni almashtirish
- 5.2 Birinchi jim tuzoq: oraliq kalit yo'q bo'lsa
- 5.3 Ikkinchi jim tuzoq: || sayoz birlashtiradi
- 5.4 Kalitni o'chirish: - va #-
- 5.5 CHECK himoya qiladi
- 6. jsonpath: JSON ichida so'rov tili
- 6.1 @? va jsonb_path_query
- 6.2 JSON_TABLE — JSON'dan jadval (PostgreSQL 17+)
- 7. JSON'ni yasash: API javobi
- 8. GIN indeksi
- 8.1 Ikki turi
- 8.2 Indeks qaysi so'rovga ishlaydi
- 9. JSONB yoki ustun: o'lchov
- 9.1 Kanon tajribasi
- 9.2 Planner JSONB ichini bilmaydi
- 9.3 Qaror
- 10. Ko'p uchraydigan xatolar
- 11. Mashqlar
- 1-mashq (oson)
- 2-mashq (o'rta)
- 3-mashq (qiyin)
- 4-mashq (qiyin)
- 12. Loyiha qadami
- 13. Real ishda
- Xulosa
- Manbalar
PostgreSQL JSONB: operatorlar, jsonpath, JSON_TABLE va GIN indeks
Qisqacha: JSONB — Postgres ustuni ichida JSON hujjat saqlash turi. Ichidan qiymat olish
->(JSON) va->>(matn) bilan, qidirish@>("shu bo'lak bormi") bilan, o'zgartirishjsonb_setva||bilan bo'ladi. U butunligicha o'qiladigan moslashuvchan ma'lumot (masalan, foydalanuvchi sozlamalari) uchun yaxshi. Filtrlanadigan, saralanadigan yoki statistikasi kerak maydon esa oddiy ustun bo'lgani ma'qul — kanon o'lchovida farq 70 baravargacha chiqdi.
Bu darsda
->,->>,#>,#>>farqini va natija turini (jsonbyokitext) aytasiz.@>,?,?|,?&bilan JSONB ichidan qidirasiz.jsonb_set,||,-,#-bilan hujjatni o'zgartirasiz va ikki jim tuzoqni chetlab o'tasiz.- jsonpath (
@?,jsonb_path_query) vaJSON_TABLEbilan JSON'ni jadvalga aylantirasiz. - GIN indeksining ikki turini taniysiz va "JSONB yoki ustun" qarorini o'lchov bilan qabul qilasiz.
vazifalarbazasiga foydalanuvchi sozlamalarini qo'shamiz (holat 01).
Oldin bilishingiz kerak: PostgreSQL ma'lumot turlari, Modellash naqshlari, Indeks turlari: GIN, GiST, BRIN, EXPLAIN ANALYZE'ni o'qish.
1. Nega bu kerak?
26-qismni keyset sahifalash bilan tugatdik: vazifalar bazasi tayyor, API undan o'qiydi. Endi 27-qism — bazani chuqurroq ishlatish. Birinchi talab frontend'dan keladi.
i18n darslarida o'quvchi interfeys tilini tanlay oladigan qilgan edik: lotin, kirill, rus, ingliz. Yana mavzu (yorug' yoki qorong'i) va bildirishnomalar bor. Hozir bular brauzerda saqlanadi. Aziz telefonida "qorong'i" ni tanlasa, kompyuterida baribir yorug' ko'radi. Sozlamalar serverda, foydalanuvchi bilan birga saqlanishi kerak.
Har sozlama uchun alohida ustun ochish mumkin: til, mavzu, email_bildirishnoma, telegram_bildirishnoma... Lekin ertaga frontend yangi tajribaviy sozlama qo'shadi — har safar ALTER TABLE va migratsiya. Sozlamalar esa doim butunligicha o'qiladi: sahifa ochilganda hammasi bir obyekt bo'lib frontend'ga ketadi.
O'xshatish: dori qutichasi. Har dori uchun shkafda alohida tortma ochmaysiz — hammasi bitta qutida, kerak bo'lganda qutini ochib olasiz. Lekin dorixona o'z omborini bunday saqlamaydi: u yerda har dori tartiblangan javonda, chunki "qaysi dorining muddati o'tdi?" degan savolga tez javob kerak. JSONB — quticha. Oddiy ustunlar — javon. Bu darsda ikkalasi qachon kerakligini o'lchab ko'ramiz.
Modellash naqshlari darsida jsonb + CHECK ni EAV o'rniga ko'rgan edik. Endi uni to'liq o'rganamiz: operatorlar, o'zgartirish, qidiruv, indeks.
2. Sozlamalar ustuni
2.1 Kanon fayli
Kanon sql/101-sozlamalar-jsonb.sql — kod o'zgarmagan, faqat qatorlarni telefon ekraniga sig'ishi uchun bo'ldik va izohlarni qisqartirdik:
ALTER TABLE foydalanuvchilar
ADD COLUMN sozlamalar jsonb NOT NULL DEFAULT '{}'::jsonb;
-- Faqat obyekt; ma'lum kalitlarning qiymati tekshiriladi,
-- noma'lum kalitlar — ruxsat (oldinga moslik)
ALTER TABLE foydalanuvchilar
ADD CONSTRAINT foydalanuvchilar_sozlamalar_check CHECK (
jsonb_typeof(sozlamalar) = 'object'
AND (NOT sozlamalar ? 'til'
OR sozlamalar->>'til' IN ('uz-Latn', 'uz-Cyrl', 'ru', 'en'))
AND (NOT sozlamalar ? 'mavzu'
OR sozlamalar->>'mavzu' IN ('yorug', 'qorongi', 'tizim'))
AND (NOT sozlamalar ? 'bildirishnoma'
OR jsonb_typeof(sozlamalar->'bildirishnoma') = 'object')
);
CREATE INDEX foydalanuvchilar_sozlamalar_idx
ON foydalanuvchilar USING gin (sozlamalar jsonb_path_ops);Uch qaror:
NOT NULL DEFAULT '{}'— sozlamasi yo'q foydalanuvchida ham bo'sh obyekt bor. IlovaNULLni alohida tekshirmaydi.CHECK— JSONB "hamma narsa kiraveradi" degani emas. Ma'lum kalitlar (til,mavzu) ruxsat etilgan qiymatlardan biri bo'lishi shart. Noma'lum kalit esa ruxsat: frontend yangi sozlama qo'shsa, baza uni rad etmaydi. Bu oldinga moslik (forward compatibility) — eski sxema yangi ilovaga xalaqit bermaydi.- GIN indeksi — keyinroq «GIN indeksi» bo'limida o'lchaymiz.
NOT sozlamalar ? 'til' OR … — "kalit yo'q bo'lsa — mayli, bor bo'lsa — to'g'ri qiymat". ? operatorini bir oz pastda ko'ramiz.
2.2 Namuna ma'lumot
102-namuna-sozlamalar.sql 8 foydalanuvchidan 6 tasiga sozlama yozadi. Holat 01 bazasida (bu darsdagi so'rovlarni o'z PostgreSQL 17.6 klasterimizda ishga tushirdik; kanon PostgreSQL 18.6 da chiqish bir xil, farqi bo'lsa — aytamiz):
SELECT id, ism, sozlamalar FROM foydalanuvchilar ORDER BY id; id | ism | sozlamalar
----+--------------------+--------------------------------------------------------------------------------------------
1 | Aziz Karimov | {"til": "uz-Latn", "mavzu": "qorongi", "bildirishnoma": {"email": true, "telegram": true}}
2 | Dilnoza Rahimova | {"til": "uz-Cyrl", "mavzu": "yorug", "bildirishnoma": {"email": false}}
3 | Sardor Tursunov | {"mavzu": "qorongi", "tajriba": {"yangi_royxat": true}}
4 | Madina Yusupova | {"til": "ru", "mavzu": "tizim"}
5 | Javohir Olimov | {}
6 | Gulnora Saidova | {"til": "uz-Latn", "bildirishnoma": {"email": true, "telegram": false}}
7 | Bekzod Nazarov | {"til": "en", "mavzu": "qorongi", "bildirishnoma": {"email": true}}
8 | Shahnoza Ergasheva | {}
(8 rows)Nimaga qarang: Sardorda (3) tajriba degan noma'lum kalit bor — CHECK uni o'tkazdi. Madinada (4) bildirishnoma umuman yo'q. Javohir va Shahnozada — bo'sh obyekt. Kalitlar alifbo tartibida emas, balki uzunligi bo'yicha, keyin alifbo bo'yicha turibdi: jsonb kalitlarni o'zi tartiblaydi (Ma'lumot turlari darsida ko'rganmiz). Bu ikkilik ichki tartib, unga tayanmang.
3. Ichiga kirish: ->, ->>, #>, #>>
3.1 To'rt operator
| Operator | Nima qaytaradi | Misol |
|---|---|---|
-> |
JSONB (kalit yoki massiv indeksi bo'yicha) | s->'til' → "uz-Latn" |
->> |
matn (text) |
s->>'til' → uz-Latn |
#> |
JSONB (yo'l bo'yicha) | s#>'{bildirishnoma,email}' → true |
#>> |
matn (yo'l bo'yicha) | s#>>'{bildirishnoma,email}' → true |
Kanon so'rovi (uzun qator bo'lingan):
\pset null '(null)'
SELECT id,
sozlamalar->'til' AS til_jsonb,
sozlamalar->>'til' AS til_text,
sozlamalar#>'{bildirishnoma,email}' AS email_jsonb,
sozlamalar#>>'{bildirishnoma,email}' AS email_text
FROM foydalanuvchilar ORDER BY id;Null display is "(null)".
id | til_jsonb | til_text | email_jsonb | email_text
----+-----------+----------+-------------+------------
1 | "uz-Latn" | uz-Latn | true | true
2 | "uz-Cyrl" | uz-Cyrl | false | false
3 | (null) | (null) | (null) | (null)
4 | "ru" | ru | (null) | (null)
5 | (null) | (null) | (null) | (null)
6 | "uz-Latn" | uz-Latn | true | true
7 | "en" | en | true | true
8 | (null) | (null) | (null) | (null)
(8 rows)\pset null '(null)' — psql'ga "NULL ni ko'rinadigan qilib yoz" deydi (psql chuqur); birinchi qatorda psql shu sozlamani tasdiqlaydi. Ikki narsaga qarang:
->natijasi qo'shtirnoqli:"uz-Latn"— bu JSON satri.->>natijasi qo'shtirnoqsiz — oddiy Postgres matni.- Kalit yo'q bo'lsa — xato emas,
NULL. Madinada (4) bildirishnoma yo'q, natija(null).
#> ning yo'li — massiv ko'rinishidagi matn: '{bildirishnoma,email}' — "avval bildirishnoma, uning ichida email". Xuddi shuni zanjir bilan ham yozish mumkin: sozlamalar->'bildirishnoma'->>'email'. Massiv elementiga raqam bilan murojaat qilinadi, 0 dan boshlab; manfiy raqam — oxiridan:
SELECT '{"teglar":["#uy","#ish"]}'::jsonb->'teglar'->0 AS birinchi,
'{"teglar":["#uy","#ish"]}'::jsonb->'teglar'->>-1 AS oxirgi; birinchi | oxirgi
----------+--------
"#uy" | #ish
(1 row)Diqqat: JSON massivida indeks 0 dan, Postgres massivida esa (keyingi darsda) 1 dan boshlanadi. Bir bazada ikki xil qoida.
3.2 Tur tuzog'i: ->> doim matn
->> hamma narsani matnga aylantiradi — true ham, 5 ham. Shuning uchun uni mantiqiy qiymat bilan solishtirib bo'lmaydi:
SELECT ism FROM foydalanuvchilar
WHERE sozlamalar->'bildirishnoma'->>'email' = true;ERROR: operator does not exist: text = boolean
LINE 2: WHERE sozlamalar->'bildirishnoma'->>'email' = true;
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts."text = boolean operatori mavjud emas". Postgres matnni mantiqiy qiymatga o'zi aylantirmaydi. ^ belgisi aynan = ostida turibdi: muammo tenglikda, uning chap va o'ng tomoni turlarida. HINT ham shuni aytadi: "aniq tur o'girishi (cast) qo'shishingiz kerak bo'lishi mumkin".
Ikki to'g'ri yo'l bor. Birinchisi — matnni o'zingiz boolean ga o'girish (::boolean). Ikkinchisi — JSONB'ni JSONB bilan solishtirish:
SELECT ism FROM foydalanuvchilar
WHERE (sozlamalar#>>'{bildirishnoma,email}')::boolean
ORDER BY id;
SELECT ism FROM foydalanuvchilar
WHERE sozlamalar->'bildirishnoma'->'email' = 'true'
ORDER BY id; ism
-----------------
Aziz Karimov
Gulnora Saidova
Bekzod Nazarov
(3 rows)
ism
-----------------
Aziz Karimov
Gulnora Saidova
Bekzod Nazarov
(3 rows)Ikkinchi so'rovda 'true' — JSONB literal (Postgres uni chap tomonga qarab jsonb deb tushunadi). Natija bir xil. Lekin keyingi bo'limdagi @> bundan ham qulayroq.
Tekshirib ko'ring:
sozlamalar->>'til' = 'ru'ishlaydimi?sozlamalar->'til' = 'ru'chi?
Javob
Birinchisi ishlaydi: ->> matn qaytaradi, 'ru' ham matn. Ikkinchisida -> JSONB qaytaradi, 'ru' esa JSONB sifatida o'qiladi — lekin ru to'g'ri JSON emas (JSON satri qo'shtirnoqda bo'ladi: '"ru"'). Postgres invalid input syntax for type json xatosini beradi. Qoida: JSONB bilan solishtirsangiz — o'ng tomon ham to'g'ri JSON bo'lsin.
4. Qidirish: @> va kalit operatorlari
4.1 @> — "shu bo'lak ichida bormi"
@> (contains) chapdagi hujjat o'ngdagi bo'lakni o'z ichiga oladimi — shuni tekshiradi. Bo'lak ichma-ich bo'lishi ham mumkin:
SELECT ism FROM foydalanuvchilar
WHERE sozlamalar @> '{"mavzu": "qorongi"}' ORDER BY id;
SELECT ism FROM foydalanuvchilar
WHERE sozlamalar @> '{"bildirishnoma": {"email": true}}'
ORDER BY id; ism
-----------------
Aziz Karimov
Sardor Tursunov
Bekzod Nazarov
(3 rows)
ism
-----------------
Aziz Karimov
Gulnora Saidova
Bekzod Nazarov
(3 rows)Ikkinchi so'rov "bildirishnoma ichida email true bo'lganlar". Turlar bilan muammo yo'q: true — JSON mantiqiy qiymati, cast kerak emas. @> ni GIN indeks qo'llaydi — u JSONB qidiruvining asosiy operatori.
4.2 ?, ?|, ?& — kalit bormi
SELECT ism,
sozlamalar ? 'til' AS til_bor,
sozlamalar ?| array['til','mavzu'] AS biri,
sozlamalar ?& array['til','mavzu'] AS ikkalasi
FROM foydalanuvchilar ORDER BY id; ism | til_bor | biri | ikkalasi
--------------------+---------+------+----------
Aziz Karimov | t | t | t
Dilnoza Rahimova | t | t | t
Sardor Tursunov | f | t | f
Madina Yusupova | t | t | t
Javohir Olimov | f | f | f
Gulnora Saidova | t | t | f
Bekzod Nazarov | t | t | t
Shahnoza Ergasheva | f | f | f
(8 rows)| Operator | Savol |
|---|---|
? |
Bu kalit bormi? |
?| |
Ro'yxatdagi kalitlardan kamida bittasi bormi? |
?& |
Hammasi bormi? |
Ular faqat yuqori darajadagi kalitlarga qaraydi: sozlamalar ? 'email' — false, chunki email bildirishnoma ichida. Ichkaridagi kalit uchun: sozlamalar->'bildirishnoma' ? 'email'.
Tekshirib ko'ring: Kalit bor, lekin qiymati JSON
null:'{"til": null}'.? 'til'nima qaytaradi?->>'til'chi?
Javob
? 'til' — true: kalit bor. ->>'til' — SQL NULL. Ya'ni ->> natijasidagi NULL "kalit yo'q" ham, "kalit bor, qiymati null" ham bo'lishi mumkin. Farq muhim bo'lsa — ? bilan tekshiring. Bu farq kanon CHECK'ida kutilmagan teshik ochadi — «Ko'p uchraydigan xatolar» bo'limida ko'rsatamiz.
5. O'zgartirish: jsonb_set, ||, -, #-
5.1 jsonb_set — bitta qiymatni almashtirish
jsonb_set(hujjat, yo'l, yangi_qiymat) — yangi hujjat qaytaradi, unda yo'l bo'yicha qiymat almashgan. Bu bo'limdagi har misol o'z BEGIN … ROLLBACK i ichida — bazani buzmaymiz, har blokni alohida ishga tushirsa bo'ladi:
BEGIN;
UPDATE foydalanuvchilar
SET sozlamalar = jsonb_set(sozlamalar,
'{bildirishnoma,telegram}', 'true')
WHERE id = 2 RETURNING sozlamalar;
ROLLBACK;BEGIN
sozlamalar
-------------------------------------------------------------------------------------------
{"til": "uz-Cyrl", "mavzu": "yorug", "bildirishnoma": {"email": false, "telegram": true}}
(1 row)
UPDATE 1
ROLLBACKDilnozaning bildirishnoma obyektiga telegram qo'shildi, email joyida qoldi. Uchinchi argument — JSONB: 'true', satr bo'lsa '"qorongi"' (ichki qo'shtirnoq bilan).
5.2 Birinchi jim tuzoq: oraliq kalit yo'q bo'lsa
Endi xuddi shunday Madinaga (4) email bildirishnomasini yoqamiz:
BEGIN;
UPDATE foydalanuvchilar
SET sozlamalar = jsonb_set(sozlamalar,
'{bildirishnoma,email}', 'true')
WHERE id = 4 RETURNING sozlamalar;
ROLLBACK;BEGIN
sozlamalar
---------------------------------
{"til": "ru", "mavzu": "tizim"}
(1 row)
UPDATE 1
ROLLBACKUPDATE 1 — "bitta qator yangilandi". Lekin hujjat o'zgarmadi. Madinada bildirishnoma obyekti yo'q, jsonb_set esa faqat oxirgi kalitni yarata oladi, oraliqdagisini emas. Xato ham, ogohlantirish ham yo'q. Bu kanon topilmasi: ilovada "saqlandi" xabari chiqadi, foydalanuvchiga esa email hech qachon kelmaydi.
To'g'ri yo'l — oraliq obyektni o'zingiz ta'minlash: coalesce(…, '{}') "yo'q bo'lsa — bo'sh obyekt" (NULL mantiqi darsidagi coalesce):
BEGIN;
UPDATE foydalanuvchilar
SET sozlamalar = jsonb_set(sozlamalar, '{bildirishnoma}',
coalesce(sozlamalar->'bildirishnoma', '{}')
|| '{"email": true}')
WHERE id = 4 RETURNING sozlamalar;
ROLLBACK;BEGIN
sozlamalar
-------------------------------------------------------------------
{"til": "ru", "mavzu": "tizim", "bildirishnoma": {"email": true}}
(1 row)
UPDATE 1
ROLLBACKEndi ishladi. Bu yerda || ni ishlatdik — u nima qilishini hozir ko'ramiz.
5.3 Ikkinchi jim tuzoq: || sayoz birlashtiradi
|| ikki obyektni birlashtiradi: o'ngdagi kalitlar chapdagini bosib ketadi. Aziz email'ni o'chirmoqchi:
BEGIN;
UPDATE foydalanuvchilar
SET sozlamalar = sozlamalar
|| '{"bildirishnoma": {"email": false}}'
WHERE id = 1 RETURNING sozlamalar;
ROLLBACK;BEGIN
sozlamalar
---------------------------------------------------------------------------
{"til": "uz-Latn", "mavzu": "qorongi", "bildirishnoma": {"email": false}}
(1 row)
UPDATE 1
ROLLBACKemail false bo'ldi — lekin telegram yo'qoldi! || faqat yuqori darajada birlashtiradi (sayoz — shallow): bildirishnoma kaliti butunligicha yangi obyekt bilan almashdi. Ichkariga kirmaydi. Shuning uchun yuqoridagi to'g'ri yo'lda || ni aynan bildirishnoma obyektining o'ziga qo'lladik.
Diqqat: Frontend ko'pincha "o'zgargan qismini" yuboradi:
{"bildirishnoma": {"email": false}}. Unisozlamalar || $1bilan yozish — boshqa ichki sozlamalarni o'chirish. Ichma-ich obyektlar uchunjsonb_setyoki ilovada chuqur birlashtirish kerak.
5.4 Kalitni o'chirish: - va #-
BEGIN;
UPDATE foydalanuvchilar SET sozlamalar = sozlamalar - 'tajriba'
WHERE id = 3 RETURNING sozlamalar;
UPDATE foydalanuvchilar
SET sozlamalar = sozlamalar #- '{bildirishnoma,telegram}'
WHERE id = 6 RETURNING sozlamalar;
ROLLBACK;BEGIN
sozlamalar
----------------------
{"mavzu": "qorongi"}
(1 row)
UPDATE 1
sozlamalar
------------------------------------------------------
{"til": "uz-Latn", "bildirishnoma": {"email": true}}
(1 row)
UPDATE 1
ROLLBACK- — yuqori darajadagi kalitni, #- — yo'l bo'yicha ichkaridagisini o'chiradi. Sardorning tajribaviy kaliti ketdi, Gulnorada faqat email qoldi. ROLLBACK — hamma o'zgarishlar bekor, baza avvalgidek.
5.5 CHECK himoya qiladi
Moslashuvchanlik chegarasiz emas. Kanon CHECK'i noto'g'ri qiymatni ham, obyekt bo'lmagan hujjatni ham rad etadi:
UPDATE foydalanuvchilar SET sozlamalar = '{"til": "uz"}'
WHERE id = 5;
UPDATE foydalanuvchilar SET sozlamalar = '[1,2]' WHERE id = 5;ERROR: new row for relation "foydalanuvchilar" violates check constraint "foydalanuvchilar_sozlamalar_check"
DETAIL: Failing row contains (5, javohir@example.com, Javohir Olimov, 2026-09-21 06:30:00+00, 6, {"til": "uz"}).
ERROR: new row for relation "foydalanuvchilar" violates check constraint "foydalanuvchilar_sozlamalar_check"
DETAIL: Failing row contains (5, javohir@example.com, Javohir Olimov, 2026-09-21 06:30:00+00, 6, [1, 2])."Yangi qator foydalanuvchilar_sozlamalar_check cheklovini buzadi". DETAIL — rad etilgan qatorning to'liq ko'rinishi. uz ruxsat ro'yxatida yo'q (uz-Latn bo'lishi kerak), [1,2] esa massiv, obyekt emas.
Tekshirib ko'ring: Nega kanon CHECK'da
tilro'yxati bor-u,bildirishnoma.emailning turi (boolean) tekshirilmaydi?
Javob
Kanon faqat "obyekt bo'lsin" deb tekshiradi — bu murosa. Har ichki kalitni CHECK'da yozish mumkin (jsonb_typeof(sozlamalar#>'{bildirishnoma,email}') = 'boolean'), lekin CHECK tez o'sadi va o'qilmay qoladi. Batafsil tekshiruv API'da — Zod sxemasi bilan; baza esa eng muhim qoidalarni oxirgi himoya sifatida ushlaydi. Bu ikki qatlamli himoya.
6. jsonpath: JSON ichida so'rov tili
6.1 @? va jsonb_path_query
jsonpath — JSON hujjat ichidan yo'l va shart bilan qidirish tili (SQL standartining bir qismi). $ — hujjatning o'zi, .kalit — ichkariga, [*] — massivning hamma elementlari, ? (…) — filtr, @ — filtr ichidagi joriy element:
SELECT ism,
jsonb_path_query_first(sozlamalar,
'$.bildirishnoma.email') AS email
FROM foydalanuvchilar
WHERE sozlamalar @? '$.bildirishnoma ? (@.email == true)'
ORDER BY id; ism | email
-----------------+-------
Aziz Karimov | true
Gulnora Saidova | true
Bekzod Nazarov | true
(3 rows)@? — "shu yo'l biror natija beradimi". jsonb_path_query_first — birinchi natijani qaytaradi. jsonpath ichida tenglik == (JS'dagidek), SQL'dagi = emas.
Massiv bilan kuchi ko'proq ko'rinadi. Hujjatda teglar ro'yxati, har birida soni:
SELECT jsonb_path_query(
'{"teglar": [{"nom":"#ish","soni":5},
{"nom":"#uy","soni":2},
{"nom":"#sport","soni":9}]}',
'$.teglar[*] ? (@.soni > 3).nom'); jsonb_path_query
------------------
"#ish"
"#sport"
(2 rows)"Teglar ichidan soni 3 dan katta bo'lganlarining nomi" — bitta ifoda. jsonb_path_query har natijani alohida qator qilib qaytaradi.
6.2 JSON_TABLE — JSON'dan jadval (PostgreSQL 17+)
JSON_TABLE JSON hujjatni oddiy jadvalga aylantiradi: siz ustunlarni va har birining yo'lini yozasiz. PostgreSQL 17 da qo'shilgan — eski versiyalarda yo'q:
\pset null '(null)'
SELECT f.ism, jt.*
FROM foydalanuvchilar f,
JSON_TABLE(f.sozlamalar, '$' COLUMNS (
til text PATH '$.til' DEFAULT 'uz-Latn' ON EMPTY,
mavzu text PATH '$.mavzu',
email boolean PATH '$.bildirishnoma.email'
)) jt
ORDER BY f.id;Null display is "(null)".
ism | til | mavzu | email
--------------------+---------+---------+--------
Aziz Karimov | uz-Latn | qorongi | t
Dilnoza Rahimova | uz-Cyrl | yorug | f
Sardor Tursunov | uz-Latn | qorongi | (null)
Madina Yusupova | ru | tizim | (null)
Javohir Olimov | uz-Latn | (null) | (null)
Gulnora Saidova | uz-Latn | (null) | t
Bekzod Nazarov | en | qorongi | t
Shahnoza Ergasheva | uz-Latn | (null) | (null)
(8 rows)Nimaga qarang: til hech qayerda (null) emas. DEFAULT 'uz-Latn' ON EMPTY — "yo'l hech narsa topmasa, shu qiymat". Sardor, Javohir va Shahnoza tilni tanlamagan — ilova ularga sukut bo'yicha lotin interfeysini ko'rsatadi, so'rov ham xuddi shunday. email ustuni esa haqiqiy boolean — endi uni WHERE email yoki count(*) FILTER (WHERE email) bilan ishlatish mumkin. JSON bilan emas, odatiy jadval bilan ishlaganday.
f, JSON_TABLE(f.sozlamalar …) — har foydalanuvchi qatori uchun uning hujjatidan jadval yasaladi. Bu LATERAL g'oyasi: o'ngdagi ifoda chapdagi qatorni ko'radi.
7. JSON'ni yasash: API javobi
Teskari yo'nalish ham kerak: oddiy ustunlardan JSON yasash. API uchun bu qulay — bazaning o'zi tayyor obyekt qaytaradi:
SELECT json_build_object('id', id, 'ism', ism,
'sozlamalar', sozlamalar)
FROM foydalanuvchilar WHERE id = 7; json_build_object
--------------------------------------------------------------------------------------------------------------------------
{"id" : 7, "ism" : "Bekzod Nazarov", "sozlamalar" : {"til": "en", "mavzu": "qorongi", "bildirishnoma": {"email": true}}}
(1 row)json_build_object argumentlarni juft-juft oladi: kalit, qiymat, kalit, qiymat. json turi kalitlar orasiga " : " qo'yadi. Ixchamroq natija uchun jsonb_build_object bor (Agregatlar darsidagi jsonb_agg bilan tanishsiz). json va jsonb farqi Ma'lumot turlari darsida: json matnni aynan saqlaydi, jsonb ikkilik ko'rinishda, takror kalitning oxirgisini qoldiradi va kalitlarni tartiblaydi. Saqlash uchun deyarli doim jsonb.
8. GIN indeksi
8.1 Ikki turi
JSONB ustuniga oddiy B-tree indeks ma'nosiz — u butun hujjatni bitta qiymat deb biladi. Indeks turlari darsidagi GIN esa hujjatni bo'laklarga ajratadi. Keyin har bo'lak qaysi qatorlarda borligini eslab qoladi — kitob oxiridagi alifbo ko'rsatkichi kabi. JSONB uchun uning ikki varianti bor:
| Variant | Qaysi operatorlar | Hajm (kanon, 1 mln qator) |
|---|---|---|
jsonb_ops (sukut) |
@>, ?, ?|, ?&, @?, @@ |
9 056 kB |
jsonb_path_ops |
faqat @>, @?, @@ |
4 472 kB |
Kanon jsonb_path_ops ni tanladi: ikki baravar kichik, "kimda qorong'i mavzu" kabi @> savollari uchun yetarli.
8.2 Indeks qaysi so'rovga ishlaydi
8 qatorli jadvalda planner indeksga qaramaydi — butun jadvalni o'qish arzon. Indeks ishlatilishi mumkinmi, shuni ko'rish uchun ketma-ket o'qishni vaqtincha "qimmat" qilamiz (EXPLAIN ANALYZE'ni o'qish):
SET enable_seqscan = off;
EXPLAIN (COSTS OFF) SELECT ism FROM foydalanuvchilar
WHERE sozlamalar @> '{"mavzu": "qorongi"}';
EXPLAIN (COSTS OFF) SELECT ism FROM foydalanuvchilar
WHERE sozlamalar->>'mavzu' = 'qorongi';
RESET enable_seqscan;SET
QUERY PLAN
-------------------------------------------------------------------
Bitmap Heap Scan on foydalanuvchilar
Recheck Cond: (sozlamalar @> '{"mavzu": "qorongi"}'::jsonb)
-> Bitmap Index Scan on foydalanuvchilar_sozlamalar_idx
Index Cond: (sozlamalar @> '{"mavzu": "qorongi"}'::jsonb)
(4 rows)
QUERY PLAN
--------------------------------------------------------------
Seq Scan on foydalanuvchilar
Filter: ((sozlamalar ->> 'mavzu'::text) = 'qorongi'::text)
(2 rows)
RESETBirinchi so'rov foydalanuvchilar_sozlamalar_idx dan foydalandi (Bitmap Index Scan). Ikkinchisi — ma'nosi bir xil, lekin ->> va = bilan yozilgan — Seq Scan qoldi, hatto taqiqlangan bo'lsa ham. GIN ->> tengligini umuman tushunmaydi. Kanon PostgreSQL 18.6 da ikkinchi rejada yana bir qator chiqadi — Disabled: true ("bu tugun taqiqlangan edi, boshqa yo'l yo'q"); PG 18 EXPLAIN'ining yangiligi, ma'nosi o'sha.
Qoida: GIN indeksli JSONB ustunga @> bilan so'rov yozing. Bu darsdagi eng amaliy qoida.
9. JSONB yoki ustun: o'lchov
9.1 Kanon tajribasi
Kanon bir xil ma'lumotni ikki shaklda saqladi: 1 mln qator JSONB hujjat (j_sozlama) va xuddi shu qiymatlar oddiy ustunlarda (u_sozlama). So'rov — "tili ru va Telegram bildirishnomasi yoqilganlar soni" (24 928 qator, 2.5 %). Har variant EXPLAIN ANALYZE bilan (kanon o'lchovi (IlmHamroh, 2026-10): PostgreSQL 18.6, Docker, bitta o'lchov):
- JSONB, indekssizParallel Seq Scan119,6 ms
- JSONB + GIN path_opsBitmap, 12 658 sahifa171,9 ms
- JSONB + ifoda indeksiB-tree (s->>'til', ...)38,2 ms
- Oddiy ustunlar + B-treeIndex Only Scan1,7 ms
Manba: IlmHamroh kanon o'lchovi, 2026-10-24: PostgreSQL 18.6, Docker (WSL2), 1 mln qator
Nimaga qarang: GIN indeksi bu savolda indekssiz variantdan ham sekinroq chiqdi. Sabab — so'rov selektiv emas: 24 928 qator jadvalning 16 000 sahifasidan 12 658 tasiga sochilgan. Indeks qatorlarni tez topdi, lekin keyin baribir deyarli hamma sahifani o'qishga to'g'ri keldi. Halol izoh: GIN o'lchovida 100 ms diskdan o'qishga ketgan (kesh sovuq edi) — bu raqam bitta o'lchov, mutlaq qiymatga emas, tartibga qarang.
Oddiy ustunlar + B-tree — 1.7 ms, 70 baravar tez: indeksning o'zida javob bor, jadvalga umuman bormaydi (Index Only Scan, Covering indekslar).
Hajm ham: JSONB jadval 125 MB, ustunli jadval 47 MB. Har JSONB qatorida kalit nomlari ("bildirishnoma", "telegram") qaytadan yoziladi; ustunda nom bir marta — jadval sxemasida.
9.2 Planner JSONB ichini bilmaydi
Eng yashirin farq. Statistika va planner darsida ko'rdik: planner har ustun qiymatlarining taqsimotini biladi. JSONB ichidagi kalitlarniki — yo'q. Kanon "mavzusi qorong'i va email yoqilgan" qatorlarni sanadi (COSTS ON — planner taxmini ko'rinsin). Ikki qatorda rows= (planner taxmini) va actual rows= (haqiqat) ni solishtiring:
Gather (cost=1000.00..26625.00 rows=2500 width=98) (actual rows=99873.00 loops=1) Seq Scan on u_sozlama (cost=0.00..18566.00 rows=100502 width=17) (actual rows=99873.00 loops=1)JSONB'da planner 2 500 qator kutdi, haqiqatda 99 873 — 40 baravar xato. Ustunlarda taxmin 100 502 — deyarli aniq. Planner kichik son kutsa, katta JOIN uchun noto'g'ri usul tanlaydi va so'rov sekinlashadi. 2 500 ma'lumotdan olinmagan: JSONB ichidagi qiymatlar haqida statistika yo'q, shuning uchun planner o'zining sukut koeffitsientlari bilan "taxminan" sanaydi. (CREATE STATISTICS ifodalar uchun ham bor — Statistika va planner; yoki ifoda indeksi, u o'z statistikasini yig'adi.)
9.3 Qaror
flowchart TD
A["Yangi maydon"] --> B{"WHERE, ORDER BY yoki<br/>JOIN'da ishlatiladimi?"}
B -- "ha" --> U["Oddiy ustun"]
B -- "yo'q" --> C{"FK yoki qat'iy<br/>tur kerakmi?"}
C -- "ha" --> U
C -- "yo'q" --> D{"Butunligicha<br/>o'qiladimi?"}
D -- "ha" --> J["JSONB + CHECK"]
D -- "yo'q" --> UKanon xulosasi: filtrlanadigan, statistikasi kerak maydon — ustun. JSONB — butun obyekt sifatida o'qiladigan, tez-tez o'zgaradigan sozlamalar. Agar JSONB ichidagi maydon bo'yicha tez-tez qidira boshlasangiz — bu uni ustunga chiqarish vaqti kelganining belgisi (yoki ifoda indeksi — 38 ms, oraliq yechim).
10. Ko'p uchraydigan xatolar
1. ->> ni boolean yoki son bilan solishtirish. operator does not exist: text = boolean. ->> doim matn. Tuzatish: ::boolean / ::int yoki @>.
2. jsonb_set oraliq kalitsiz. Xato yo'q, UPDATE 1, lekin hujjat o'zgarmaydi. Tuzatish: coalesce(s->'ota', '{}') || '{"kalit": …}' bilan ota obyektni ta'minlang yoki natijani RETURNING bilan tekshiring.
3. || bilan ichma-ich obyektni yangilash. Qo'shni ichki kalitlar o'chadi. Tuzatish: jsonb_set bilan aniq yo'lga yozing.
4. GIN bor, so'rov ->> bilan. Indeks ishlamaydi, Seq Scan. Tuzatish: @> yoki ifoda indeksi ((s->>'til')).
5. "Hamma narsa JSONB'da". Filtrlanadigan maydonlar hujjat ichida: jadval 2.7 baravar katta, planner adashadi, FK qo'yib bo'lmaydi. Tuzatish: qidiriladigan maydonni ustunga chiqaring.
6. JSON null CHECK'dan o'tib ketadi. Biz o'z klasterimizda sinadik — kanon CHECK'i shu qiymatni qabul qildi:
BEGIN;
UPDATE foydalanuvchilar SET sozlamalar = '{"til": null}'
WHERE id = 5
RETURNING sozlamalar, sozlamalar ? 'til' AS kalit_bor;
ROLLBACK;BEGIN
sozlamalar | kalit_bor
---------------+-----------
{"til": null} | t
(1 row)
UPDATE 1
ROLLBACKNega? Kalit bor, shuning uchun NOT sozlamalar ? 'til' — false. ->>'til' esa NULL, va NULL IN ('uz-Latn', …) — NULL. false OR NULL — NULL. CHECK esa NULL natijani "buzilmadi" deb hisoblaydi (NULL mantiqi). Ilova uchun {"til": null} — g'alati holat: kalit bor, til yo'q. Tuzatish: shartni jsonb_typeof(sozlamalar->'til') = 'string' AND … bilan kuchaytirish. Halol aytamiz: kanon bu teshikni yopmagan va yopmaydi — 101 qo'llangan, kanon sxemasi qotgan, ilova (API va Zod) til: null yubormaydi. O'z loyihangizda tuzatish yangi migratsiya faylida bo'ladi (Loyiha qadamidagi qoida); 4-mashqda shuni ROLLBACK ichida sinab ko'rasiz. mavzu da ham xuddi shu teshik bor.
11. Mashqlar
Mashqlar kurs/mashqlar/27/01-jsonb/ da. Hammasi holat 01 bazasida, o'zgartiradiganlari BEGIN … ROLLBACK ichida; yechimlar tekshirilgan (biz ishga tushirdik, PostgreSQL 17.6).
1-mashq (oson)
Telegram bildirishnomasi yoqilgan (true) foydalanuvchilarning ismini chiqaring. Gulnorada telegram bor, lekin false — u chiqmasligi kerak. Ishora: «@> — "shu bo'lak ichida bormi"» bo'limi, ichma-ich bo'lak.
Yechim
SELECT ism FROM foydalanuvchilar
WHERE sozlamalar @> '{"bildirishnoma": {"telegram": true}}'; ism
--------------
Aziz Karimov
(1 row)Faqat Aziz. @> qiymatni ham tekshiradi — Gulnoraning telegram: false bo'lagi {"telegram": true} ni o'z ichiga olmaydi. Bu so'rov GIN indeksidan foydalana oladi.
2-mashq (o'rta)
Madina (4) va Gulnora (6) uchun Telegram bildirishnomasini yoqing. Gulnoraning email: true qiymati saqlanib qolishi shart, Madinada esa bildirishnoma obyekti umuman yo'q. Bitta UPDATE bilan, natijani RETURNING id, sozlamalar->'bildirishnoma' bilan ko'rsating, oxirida ROLLBACK. Ishora: «Birinchi jim tuzoq» bo'limidagi coalesce(…, '{}') || … naqshi.
Yechim
BEGIN;
UPDATE foydalanuvchilar
SET sozlamalar = jsonb_set(sozlamalar, '{bildirishnoma}',
coalesce(sozlamalar->'bildirishnoma', '{}')
|| '{"telegram": true}')
WHERE id IN (4, 6)
RETURNING id, sozlamalar->'bildirishnoma' AS bildirishnoma;
ROLLBACK;BEGIN
id | bildirishnoma
----+-----------------------------------
4 | {"telegram": true}
6 | {"email": true, "telegram": true}
(2 rows)
UPDATE 2
ROLLBACKMadinaga yangi obyekt yaratildi, Gulnorada email joyida qoldi va telegram false dan true ga o'zgardi. Oddiy jsonb_set(s, '{bildirishnoma,telegram}', 'true') Madinada jim hech narsa qilmasdi, s || '{"bildirishnoma": {"telegram": true}}' esa Gulnoraning email ini o'chirardi. (RETURNING qatorlari id tartibida chiqdi, lekin UPDATE tartibni kafolatlamaydi — kerak bo'lsa saralash keyingi SELECT da.)
3-mashq (qiyin)
Har interfeys tili bo'yicha nechta foydalanuvchi bor va ulardan nechtasi email bildirishnoma oladi — bitta so'rov. Tilni tanlamaganlar uz-Latn hisoblansin, email kaliti yo'qlar — false. Natija: til, email_oladi, jami, til bo'yicha alifbo tartibida. Ishora: JSON_TABLE va DEFAULT … ON EMPTY («JSON_TABLE — JSON'dan jadval» bo'limi), count(*) FILTER (WHERE …) — Agregatlar.
Yechim
SELECT jt.til,
count(*) FILTER (WHERE jt.email) AS email_oladi,
count(*) AS jami
FROM foydalanuvchilar f,
JSON_TABLE(f.sozlamalar, '$' COLUMNS (
til text PATH '$.til' DEFAULT 'uz-Latn' ON EMPTY,
email boolean PATH '$.bildirishnoma.email'
DEFAULT false ON EMPTY)) jt
GROUP BY jt.til ORDER BY jt.til; til | email_oladi | jami
---------+-------------+------
en | 1 | 1
ru | 0 | 1
uz-Cyrl | 0 | 1
uz-Latn | 2 | 5
(4 rows)uz-Latn — 5 ta: Aziz va Gulnora tanlagan, uchtasi sukut bo'yicha. Email olayotganlar ikkita (Aziz, Gulnora). JSON_TABLE dan keyin bu oddiy GROUP BY — JSON bilan ishlash tugadi, jadval bilan ishlash boshlandi. PostgreSQL 16 va eskida JSON_TABLE yo'q: u yerda coalesce(s->>'til', 'uz-Latn') va coalesce((s#>>'{bildirishnoma,email}')::boolean, false) bilan yoziladi.
4-mashq (qiyin)
«Ko'p uchraydigan xatolar» dagi JSON null teshigini yoping — til va mavzu uchun. Kanon cheklovini o'chirib, xuddi shu nom bilan kuchliroq cheklov qo'shing (bitta ALTER TABLE ichida DROP CONSTRAINT …, ADD CONSTRAINT …). Keyin Javohirga (5) '{"til": null}' yozib ko'ring — rad etilishi kerak. Hammasi BEGIN … ROLLBACK ichida: bu mashq, migratsiya emas. Ishora: kalit bor bo'lsa, qiymat avval jsonb_typeof(…) = 'string' bo'lsin, keyin ro'yxatda.
Yechim
BEGIN;
ALTER TABLE foydalanuvchilar
DROP CONSTRAINT foydalanuvchilar_sozlamalar_check,
ADD CONSTRAINT foydalanuvchilar_sozlamalar_check CHECK (
jsonb_typeof(sozlamalar) = 'object'
AND (NOT sozlamalar ? 'til'
OR (jsonb_typeof(sozlamalar->'til') = 'string'
AND sozlamalar->>'til'
IN ('uz-Latn', 'uz-Cyrl', 'ru', 'en')))
AND (NOT sozlamalar ? 'mavzu'
OR (jsonb_typeof(sozlamalar->'mavzu') = 'string'
AND sozlamalar->>'mavzu' IN ('yorug', 'qorongi', 'tizim')))
AND (NOT sozlamalar ? 'bildirishnoma'
OR jsonb_typeof(sozlamalar->'bildirishnoma') = 'object')
);
UPDATE foydalanuvchilar SET sozlamalar = '{"til": null}'
WHERE id = 5;
ROLLBACK;BEGIN
ALTER TABLE
ERROR: new row for relation "foydalanuvchilar" violates check constraint "foydalanuvchilar_sozlamalar_check"
DETAIL: Failing row contains (5, javohir@example.com, Javohir Olimov, 2026-09-21 06:30:00+00, 6, {"til": null}).
ROLLBACKALTER TABLE o'tdi — demak mavjud 8 qatorning hammasi yangi shartga mos (Postgres yangi cheklovni qo'shishda har qatorni tekshiradi). {"til": null} endi rad etildi: jsonb_typeof JSON null uchun 'null' qaytaradi, 'null' = 'string' — false, false AND … — false, NULL emas. Haqiqiy loyihada bu blok ROLLBACK siz, yangi raqamli migratsiya faylida turadi.
12. Loyiha qadami
Holat 64 (26-qism yakuni) → holat 01. 27-qismning birinchi o'zgarishi — ikki fayl:
sql/101-sozlamalar-jsonb.sql— ustun, CHECK va GIN indeks (to'liq matni «Kanon fayli» bo'limida);sql/102-namuna-sozlamalar.sql— 6 foydalanuvchiga namuna sozlamalar.
Nega 101, 015 emas? 27-qism fayllari 101 dan boshlanadi: 001–014 — 26-qismniki, ular orasiga keyin yana fayl qo'shilsa, raqamlar to'qnashmasin. Namuna fayli (102) — kanon qoidasi bo'yicha: nomida namuna bor fayllar prodakshn bazasiga qo'llanmaydi.
102 ning boshi (kanon, qatorlar bo'lingan):
UPDATE foydalanuvchilar SET sozlamalar = s.j::jsonb
FROM (VALUES
('aziz@example.com',
'{"til": "uz-Latn", "mavzu": "qorongi",
"bildirishnoma": {"email": true, "telegram": true}}'),
('dilnoza@example.com',
'{"til": "uz-Cyrl", "mavzu": "yorug",
"bildirishnoma": {"email": false}}'),
-- … yana 4 foydalanuvchi: madina, gulnora, sardor, bekzod
) AS s(email, j)
WHERE foydalanuvchilar.email = s.email;To'liq faylda 6 qator — «Namuna ma'lumot» bo'limidagi jadvaldagi qiymatlar. Qo'llash (26-qismdagi kabi, har fayl bitta tranzaksiyada):
psql -X -1 -v ON_ERROR_STOP=1 \
-d postgres://postgres@127.0.0.1:5499/vazifalar \
-f sql/101-sozlamalar-jsonb.sql
psql -X -1 -v ON_ERROR_STOP=1 \
-d postgres://postgres@127.0.0.1:5499/vazifalar \
-f sql/102-namuna-sozlamalar.sqlTekshiruv: «Namuna ma'lumot» bo'limidagi SELECT xuddi o'sha 8 qatorni bersin. Commit:
git add sql/101-sozlamalar-jsonb.sql sql/102-namuna-sozlamalar.sql
M='db: foydalanuvchi sozlamalari — jsonb, CHECK va GIN indeks'
M+=' (101, 102-namuna)'
git commit -m "$M"26-qismdagi qoida 27 da ham amal qiladi: qo'llangan fayl o'zgartirilmaydi. «Ko'p uchraydigan xatolar» dagi JSON null teshigini yopmoqchi bo'lsangiz — 101 ni tahrirlamaysiz, yangi fayl yozasiz (ALTER TABLE … DROP CONSTRAINT …, ADD CONSTRAINT …). Sabab: 101 allaqachon boshqa bazalarda (hamkasbingizda, serverda) qo'llangan — u yerda tahrirlangan fayl hech qachon qayta ishlamaydi va bazalar bir-biridan farqlanib ketadi.
API hali sozlamalarni o'qimaydi — bu ustun hozircha faqat bazada. Uni ORM orqali API'ga ulash — Prisma darslarida (ORM, query builder va raw SQL dan boshlab).
13. Real ishda
- Sozlamalar, metama'lumot, integratsiya javoblari. To'lov tizimi (Click, Payme) qaytargan to'liq javobni
jsonbda saqlash — keyin "nima kelgan edi?" degan savolga javob bor. Lekin summa, holat, sana — alohida ustunlarda. - Audit jadvallari. Kanon
vazifa_tarixiningeskivayangiustunlari aynanjsonb(Soft delete va tarix). - ORM'larda. Prisma
Jsonturi, Drizzlejsonb()— ichida shu tur; filtrlash imkoniyatlari esa cheklangan, murakkab so'rov uchun xom SQL kerak bo'ladi (Prisma: raw SQL va TypedSQL darsida ko'ramiz). - MongoDB bilan solishtirish. "Hujjat saqlash kerak — Mongo olaylik" degan fikr ko'p uchraydi. Ko'pincha Postgres'ning
jsonbi yetarli; farqlarni Mongo darslarida o'lchaymiz. - Intervyuda: "
jsonvajsonbfarqi?", "JSONB'ni qanday indekslaysiz?", "Qachon JSONB ishlatmaysiz?" — javobda@>+ GIN, ifoda indeksi va planner statistikasini tilga oling.
Xulosa
->JSONB,->>matn qaytaradi;->>ni boolean bilan solishtirish — xato,::booleanyoki@>kerak.@>— JSONB qidiruvining asosiy operatori, GIN uni qo'llaydi;->>tengligini GIN qo'llamaydi.jsonb_setoraliq kalit yo'q bo'lsa jim hech narsa qilmaydi;||sayoz — ichki obyektni butunlay almashtiradi.- jsonpath (
@?,jsonb_path_query) — JSON ichida filtr;JSON_TABLE(PG 17+) — JSON'dan oddiy jadval. - CHECK bilan JSONB "nazoratli moslashuvchan" bo'ladi: ma'lum kalitlar tekshiriladi, noma'lumlari o'tadi.
- Kanon o'lchovi: ustun + B-tree 1.7 ms, JSONB + GIN 171.9 ms; jadval 47 va 125 MB; planner JSONB ichida 40 baravar adashdi. Filtrlanadigan maydon — ustun.
Keyingi dars: Massivlar, range, domain va maxsus turlar — Postgres'ning boy tur tizimi: massivlar, vaqt oraliqlari va kesishmaydigan bronlar, o'z turingiz (DOMAIN) va registrga befarq matn.
Manbalar
- PostgreSQL 18 hujjati — JSON Types (
jsonbindekslash,jsonb_opsvajsonb_path_ops): https://www.postgresql.org/docs/18/datatype-json.html - PostgreSQL 18 hujjati — JSON Functions and Operators (
jsonb_set,||, jsonpath,JSON_TABLE): https://www.postgresql.org/docs/18/functions-json.html - PostgreSQL 17 reliz eslatmalari —
JSON_TABLEqo'shilgani: https://www.postgresql.org/docs/17/release-17.html - IlmHamroh kanon o'lchovi (PostgreSQL 18.6, Docker, 1 mln qator, 2026-10-24); darsdagi so'rovlar — biz ishga tushirdik (PostgreSQL 17.6, Windows 11), 2026-10-25.
Izohlar (0)
Izoh yozish uchun kiring.
- Hozircha izoh yo'q. Birinchi bo'ling!