88 / 100

COMPOSITE TYPES

Tarkibiy turlar

Ushbu qo'llanmada PostgreSQLda tarkibiy (kompozit) ma'lumot turlarini yaratish, ulardan jadval ustunlarida foydalanish va kompozit maydonlarni boshqarishni o'rganasiz.

PostgreSQL tarkibiy turlariga kirish

Tarkibiy tur (Composite Type) — bu bir nechta nomlangan maydonlar va ularning ma'lumot turlaridan tashkil topgan strukturalangan ma'lumot turidir. Boshqa dasturlash tillaridagi struct yoki record tushunchasiga o'xshaydi.

PostgreSQL kompozit turlardan xuddi oddiy turlar kabi foydalanishga ruxsat beradi: ularni jadval ustuni turi, funksiya argumenti yoki qaytaruvchi qiymati sifatida ishlatish mumkin.

Tarkibiy turni yaratish sintaksisi:

query.sql
CREATE TYPE type_name AS (
    field1 data_type,
    field2 data_type,
    ...
);

Sintaksis tushuntirishi:

  • type_name — yaratilayotgan yangi kompozit turning nomi.
  • field1, field2... — uning tarkibidagi maydonlar va ularning ma'lumot turlari.

Misol uchun, kenglik va uzunlikni o'z ichiga olgan geografik koordinatalar uchun coordinate turini yaratamiz:

query.sql
CREATE TYPE coordinate AS (
    latitude DEC,
    longitude DEC
);

Tarkibiy turdan jadvalda foydalanish

Yaratilgan turni oddiy ustun turi sifatida ko'rsatish mumkin:

query.sql
DROP TABLE IF EXISTS warehouse_locations CASCADE;

CREATE TABLE warehouse_locations (
    warehouse_id INT PRIMARY KEY,
    location coordinate
);

Kompozit qiymatlarni kiritish (INSERT)

Kompozit qiymatni shakllantirish uchun ROW kalit so'zi va qavslardan foydalaniladi:

query.sql
ROW(value1, value2, ...)

Misol:

query.sql
INSERT INTO warehouse_locations (warehouse_id, location)
VALUES (1, ROW(37.318686, -121.871019))
RETURNING *;

Natija:

matn
 warehouse_id |        location         
--------------+-------------------------
            1 | (37.318686,-121.871019)

Shuningdek, nuqta belgisi (composite_column.field_name) orqali alohida maydonlarni aniq ko'rsatib ham kiritish mumkin:

query.sql
INSERT INTO warehouse_locations (
    warehouse_id,
    location.latitude,
    location.longitude
)
VALUES (2, 37.650972, -122.398659)
RETURNING *;

Kompozit maydonlarni o'qish (SELECT)

Kompozit ustunning ichki maydonini o'qish uchun ustun nomini albatta qavs ichiga olish kerak:

query.sql
(composite_column).field_name

[!IMPORTANT] Agar qavslar qo'yilmasa (location.latitude), PostgreSQL location so'zini jadval nomi deb o'ylab, xatolik berishi mumkin.

Misol:

query.sql
SELECT
  warehouse_id,
  (location).latitude,
  (location).longitude
FROM
  warehouse_locations;

Natija:

matn
 warehouse_id | latitude  |  longitude  
--------------+-----------+-------------
            1 | 37.318686 | -121.871019
            2 | 37.650972 | -122.398659

Barcha maydonlarni birvarakayiga ochib (yoyib) ko'rsatish uchun yulduzcha .* dan foydalanish mumkin:

query.sql
SELECT
  warehouse_id,
  (location).*
FROM
  warehouse_locations;

Kompozit maydonlarni yangilash (UPDATE)

Alohida bitta maydonni yangilashda SET bandida qavssiz nuqta sintaksisi ishlatiladi:

query.sql
UPDATE warehouse_locations
SET
  location.latitude = 37.650971,
  location.longitude = -122.398658
WHERE
  warehouse_id = 1
RETURNING *;

Butun kompozit qiymatni to'liq almashtirish uchun esa ROW(...) beriladi:

query.sql
UPDATE warehouse_locations
SET
  location = ROW(37.650971, -122.398658)
WHERE
  warehouse_id = 1
RETURNING *;

Maydonlarga cheklovlar qo'yish (CREATE DOMAIN)

Tarkibiy turlar o'zlarining ichki maydonlarida to'g'ridan-to'g'ri NOT NULL yoki CHECK cheklovlarini qo'llab-quvvatlamaydi.

Agar ichki maydonlar hech qachon NULL bo'lmasligini ta'minlash kerak bo'lsa, kompozit tur ustiga domen (DOMAIN) quriladi:

query.sql
CREATE DOMAIN coordinate_domain 
AS coordinate 
CHECK (
  (VALUE).latitude IS NOT NULL
  AND (VALUE).longitude IS NOT NULL
);

Endi jadval ustunini ushbu domen turiga o'zgartiramiz:

query.sql
ALTER TABLE warehouse_locations
ALTER COLUMN location TYPE coordinate_domain;

Endi ichki maydonlarga NULL kiritishga urinilsa:

query.sql
INSERT INTO warehouse_locations (warehouse_id, location)
VALUES (3, ROW(NULL, NULL));

PostgreSQL qat'iy cheklov bilan to'xtatadi:

matn
ERROR:  value for domain coordinate_domain violates check constraint "coordinate_domain_check"

Xulosa

  • Tarkibiy turlar (Composite Types) bog'liq bir nechta qiymatlarni bitta ustunda ixcham saqlash imkonini beradi.
  • Kompozit qiymatlar ROW(val1, val2) yordamida yoziladi.
  • Qiymatlarni o'qishda chalkashliklarning oldini olish uchun ustun nomi qavsga olinadi: (location).latitude.
  • Ichki maydonlarga tekshiruv va cheklovlar qo'yish uchun CREATE DOMAIN dan foydalaniladi.