11-bo‘lim
Massivlar
Massiv ustunlari, indeks 1 dan boshlanishi, ANY va @> operatorlari, unnest bilan qatorlarga yoyish va massiv qachon to'g'ri tanlov.
Ushbu bo‘lim mundarijasi
PostgreSQL da ustun massiv bo'lishi mumkin. Bu relyatsion modelga qarshi ko'rinadi, lekin ba'zi vazifalarda juda qulay.
CREATE TABLE maqola (
id int GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
sarlavha text NOT NULL,
teglar text[] NOT NULL DEFAULT '{}',
ballar int[]
);
INSERT INTO maqola (sarlavha, teglar, ballar) VALUES
('PostgreSQL asoslari', ARRAY['baza','postgresql','sql'], ARRAY[5,4,5]),
('Indekslar haqida', ARRAY['baza','optimizatsiya'], ARRAY[4,4,3]),
('JSONB bilan ishlash', ARRAY['baza','postgresql','json'],ARRAY[5,5,5]),
('Tarmoq asoslari', ARRAY['tarmoq'], ARRAY[3,4]),
('Bo''sh maqola', '{}', NULL);
Massiv yaratish va o'qish #
Ikki xil yozuv bor va ikkalasi bir xil:
SELECT ARRAY[1,2,3] AS birinchi_usul,
'{4,5,6}'::int[] AS ikkinchi_usul,
array_length(ARRAY['a','b','c'], 1) AS uzunlik;
birinchi_usul | ikkinchi_usul | uzunlik
---------------+---------------+---------
{1,2,3} | {4,5,6} | 3
(1 row)
Deyarli barcha dasturlash tillarida massiv 0 dan boshlanadi. SQL da esa - 1 dan.
| Ifoda | Natija |
|---|---|
ARRAY['a','b','c'][1] | a |
ARRAY['a','b','c'][0] | bo'sh (NULL) |
Diqqat qiling: chegaradan tashqari indeks xato bermaydi,
u shunchaki NULL qaytaradi. Bu jimgina xatolarga olib
kelishi mumkin.
array_length(massiv, 1) dagi 1 - bu o'lchov raqami.
PostgreSQL ko'p o'lchovli massivlarni ham qo'llab-quvvatlaydi.
Elementga murojaat va kesim olish:
SELECT sarlavha,
teglar[1] AS birinchi_teg,
teglar[2:3] AS kesim,
array_length(teglar, 1) AS teglar_soni
FROM maqola
WHERE sarlavha = 'PostgreSQL asoslari';
sarlavha | birinchi_teg | kesim | teglar_soni
---------------------+--------------+------------------+-------------
PostgreSQL asoslari | baza | {postgresql,sql} | 3
(1 row)
Qidirish #
Massiv ichida qiymat bormi - buni ANY bilan tekshiriladi:
SELECT sarlavha, teglar
FROM maqola
WHERE 'postgresql' = ANY(teglar)
ORDER BY id;
sarlavha | teglar
---------------------+------------------------
PostgreSQL asoslari | {baza,postgresql,sql}
JSONB bilan ishlash | {baza,postgresql,json}
(2 rows)
Yana kuchliroq operatorlar ham bor:
| Operator | Ma'nosi |
|---|---|
@> | Chap massiv o'ngdagini o'z ichiga oladi |
<@ | Chap massiv o'ngdagining ichida |
&& | Ikkalasida umumiy element bor |
SELECT sarlavha, teglar
FROM maqola
WHERE teglar @> ARRAY['baza','postgresql']
ORDER BY id;
sarlavha | teglar
---------------------+------------------------
PostgreSQL asoslari | {baza,postgresql,sql}
JSONB bilan ishlash | {baza,postgresql,json}
(2 rows)
Bu "ikkala teg ham bo'lishi shart" degani. Faqat bittasi
yetarli bo'lsa, && ishlatiladi:
SELECT sarlavha
FROM maqola
WHERE teglar && ARRAY['tarmoq','json']
ORDER BY id;
sarlavha
---------------------
JSONB bilan ishlash
Tarmoq asoslari
(2 rows)
unnest - massivni qatorlarga yoyish #
Massivni oddiy jadvalga aylantirish - eng ko'p ishlatiladigan amal:
SELECT teg, count(*) AS soni
FROM maqola, unnest(teglar) AS teg
GROUP BY teg
ORDER BY soni DESC, teg;
teg | soni
---------------+------
baza | 3
postgresql | 2
json | 1
optimizatsiya | 1
sql | 1
tarmoq | 1
(6 rows)
Bu "eng mashhur teglar" hisoboti. unnest har massiv
elementini alohida qatorga aylantirdi.
Teskari amal - array_agg (8-bo'limda ko'rgandik):
SELECT array_agg(sarlavha ORDER BY id) AS sarlavhalar
FROM maqola
WHERE 'baza' = ANY(teglar);
sarlavhalar
------------------------------------------------------------------
{"PostgreSQL asoslari","Indekslar haqida","JSONB bilan ishlash"}
(1 row)
Massiv ustida hisob #
SELECT sarlavha,
ballar,
(SELECT round(avg(b), 2) FROM unnest(ballar) AS b) AS ortacha
FROM maqola
WHERE ballar IS NOT NULL
ORDER BY id;
sarlavha | ballar | ortacha
---------------------+---------+---------
PostgreSQL asoslari | {5,4,5} | 4.67
Indekslar haqida | {4,4,3} | 3.67
JSONB bilan ishlash | {5,5,5} | 5.00
Tarmoq asoslari | {3,4} | 3.50
(4 rows)
Massivni o'zgartirish #
SELECT ARRAY['a','b'] || 'c'::text AS oxiriga_qoshish,
ARRAY['a','b'] || ARRAY['c','d'] AS ikki_massiv,
array_remove(ARRAY['a','b','a'], 'a') AS olib_tashlash,
array_position(ARRAY['x','y','z'], 'y') AS orni;
oxiriga_qoshish | ikki_massiv | olib_tashlash | orni
-----------------+-------------+---------------+------
{a,b,c} | {a,b,c,d} | {b} | 2
(1 row)
ARRAY['a','b'] || 'c' deb yozsangiz, PostgreSQL xato beradi:
malformed array literal.
Sabab: 'c' ni ikki xil tushunish mumkin - element sifatida yoki
massiv literali sifatida. Baza taxmin qilmaydi.
Yechim - turni ochiq aytish: 'c'::text. Shunda || uni element
deb qabul qiladi.
Bu massivning eng jiddiy cheklovi.
muallif_id int[] deb yozsangiz, PostgreSQL bu raqamlar
haqiqatan muallif jadvalida borligini tekshirmaydi.
O'chirilgan muallifning id si massivda qolib ketaveradi.
Alohida bog'lovchi jadvalda esa REFERENCES ishlaydi va
baza butunlikni o'zi kafolatlaydi.
Shuning uchun identifikatorlarni massivda saqlamang. Massiv oddiy, mustaqil qiymatlar uchun: teglar, kalit so'zlar, ranglar.
- Uchta elementli massiv yarating va uzunligini toping.
massiv[0]ga murojaat qiling - nima qaytdi?- Chegaradan tashqari indeks nima uchun xato bermasligini yozing.
ANYbilan ma'lum tegli maqolalarni toping.@>va&&farqini misol bilan ko'rsating.unnestbilan eng mashhur uchta tegni chiqaring.array_aggbilan teskari amalni bajaring.- Massivga element qo'shing va olib tashlang.
- Massiv qachon alohida jadvaldan yaxshiroq ekanini yozing.
- Nima uchun massivda identifikator saqlash xavfli ekanini tushuntiring.
Xulosa #
- PostgreSQL da ustun massiv bo'lishi mumkin:
text[],int[]. - Massiv indeksi 1 dan boshlanadi, 0 dan emas.
- Chegaradan tashqari indeks xato bermaydi - u
NULLqaytaradi. = ANY(massiv)- ichida bormi degan savolga javob beradi.@>hammasini,&&esa kamida bittasini talab qiladi.unnestmassivni qatorlarga yoyadi - guruhlash uchun zarur.array_aggteskari amalni bajaradi.||bilan qo'shish,array_removebilan olib tashlash mumkin.- Massiv oddiy, mustaqil qiymatlar uchun: teglar, kalit so'zlar.
- Massivga tashqi kalit qo'yib bo'lmaydi - identifikatorlarni unda saqlamang.
Keyingi bo'limda PostgreSQL ning eng mashhur imkoniyati - JSONB bilan tanishamiz.
O‘qish tarixini saqlamoqchimisiz?
Tizimga kirsangiz, tugatgan bo‘limlaringiz saqlanadi va qoldirgan joyingizdan davom etasiz.
Xatolik topdingizmi?
Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.