11-bo‘lim

Massivlar

Massiv ustunlari, indeks 1 dan boshlanishi, ANY va @> operatorlari, unnest bilan qatorlarga yoyish va massiv qachon to'g'ri tanlov.

🕑 11 daqiqa o‘qish 📄 500 so‘z 👁 0 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Massiv yaratish va o'qish
  2. Qidirish
  3. unnest - massivni qatorlarga yoyish
  4. Massiv ustida hisob
  5. Massivni o'zgartirish
  6. Xulosa

PostgreSQL da ustun massiv bo'lishi mumkin. Bu relyatsion modelga qarshi ko'rinadi, lekin ba'zi vazifalarda juda qulay.

SQL
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:

SQL
SELECT ARRAY[1,2,3] AS birinchi_usul,
       '{4,5,6}'::int[] AS ikkinchi_usul,
       array_length(ARRAY['a','b','c'], 1) AS uzunlik;
Natija
 birinchi_usul | ikkinchi_usul | uzunlik
---------------+---------------+---------
 {1,2,3}       | {4,5,6}       |       3
(1 row)
Massiv indeksi 1 dan boshlanadi

Deyarli barcha dasturlash tillarida massiv 0 dan boshlanadi. SQL da esa - 1 dan.

IfodaNatija
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:

SQL
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';
Natija
      sarlavha       | birinchi_teg |      kesim       | teglar_soni
---------------------+--------------+------------------+-------------
 PostgreSQL asoslari | baza         | {postgresql,sql} |           3
(1 row)

Qidirish #

Massiv ichida qiymat bormi - buni ANY bilan tekshiriladi:

SQL
SELECT sarlavha, teglar
FROM maqola
WHERE 'postgresql' = ANY(teglar)
ORDER BY id;
Natija
      sarlavha       |         teglar
---------------------+------------------------
 PostgreSQL asoslari | {baza,postgresql,sql}
 JSONB bilan ishlash | {baza,postgresql,json}
(2 rows)

Yana kuchliroq operatorlar ham bor:

OperatorMa'nosi
@>Chap massiv o'ngdagini o'z ichiga oladi
<@Chap massiv o'ngdagining ichida
&&Ikkalasida umumiy element bor
SQL
SELECT sarlavha, teglar
FROM maqola
WHERE teglar @> ARRAY['baza','postgresql']
ORDER BY id;
Natija
      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:

SQL
SELECT sarlavha
FROM maqola
WHERE teglar && ARRAY['tarmoq','json']
ORDER BY id;
Natija
      sarlavha
---------------------
 JSONB bilan ishlash
 Tarmoq asoslari
(2 rows)

unnest - massivni qatorlarga yoyish #

Massivni oddiy jadvalga aylantirish - eng ko'p ishlatiladigan amal:

SQL
SELECT teg, count(*) AS soni
FROM maqola, unnest(teglar) AS teg
GROUP BY teg
ORDER BY soni DESC, teg;
Natija
      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):

SQL
SELECT array_agg(sarlavha ORDER BY id) AS sarlavhalar
FROM maqola
WHERE 'baza' = ANY(teglar);
Natija
                           sarlavhalar
------------------------------------------------------------------
 {"PostgreSQL asoslari","Indekslar haqida","JSONB bilan ishlash"}
(1 row)

Massiv ustida hisob #

SQL
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;
Natija
      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 #

SQL
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;
Natija
 oxiriga_qoshish | ikki_massiv | olib_tashlash | orni
-----------------+-------------+---------------+------
 {a,b,c}         | {a,b,c,d}   | {b}           |    2
(1 row)
Turni ochiq ko'rsatish kerak bo'ladigan joy

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.

Massiv yoki alohida jadval - qaysi biri? MASSIV mos keladi Qiymatlar oddiy (matn, son) Ular faqat shu qatorga tegishli Alohida xossalari yo'q Ularga alohida murojaat qilinmaydi misol: teglar, ranglar ALOHIDA JADVAL kerak Elementning o'z xossalari bor Ularni alohida qidirish kerak Boshqa jadval bilan bog'lanadi Cheklov yoki tashqi kalit kerak misol: buyurtma qatorlari Shubha bo'lsa - alohida jadval Massivdan jadvalga o'tish oson, teskarisi esa ancha qiyin Massivga tashqi kalit qo'yib bo'lmaydi - butunlik kafolatlanmaydi
Massiv - qulaylik, alohida jadval - nazorat
Massivga tashqi kalit qo'yib bo'lmaydi

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.

Amaliy topshiriq
  1. Uchta elementli massiv yarating va uzunligini toping.
  2. massiv[0] ga murojaat qiling - nima qaytdi?
  3. Chegaradan tashqari indeks nima uchun xato bermasligini yozing.
  4. ANY bilan ma'lum tegli maqolalarni toping.
  5. @> va && farqini misol bilan ko'rsating.
  6. unnest bilan eng mashhur uchta tegni chiqaring.
  7. array_agg bilan teskari amalni bajaring.
  8. Massivga element qo'shing va olib tashlang.
  9. Massiv qachon alohida jadvaldan yaxshiroq ekanini yozing.
  10. 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 NULL qaytaradi.
  • = ANY(massiv) - ichida bormi degan savolga javob beradi.
  • @> hammasini, && esa kamida bittasini talab qiladi.
  • unnest massivni qatorlarga yoyadi - guruhlash uchun zarur.
  • array_agg teskari amalni bajaradi.
  • || bilan qo'shish, array_remove bilan 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.

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.