Tarkibiy turlar
Ushbu qo'llanmada PostgreSQLda tarkibiy (kompozit) ma'lumot turlarini yaratish, ulardan jadval ustunlarida foydalanish va kompozit maydonlarni boshqarishni o'rganasiz.
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:
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:
CREATE TYPE coordinate AS (
latitude DEC,
longitude DEC
);
Yaratilgan turni oddiy ustun turi sifatida ko'rsatish mumkin:
DROP TABLE IF EXISTS warehouse_locations CASCADE;
CREATE TABLE warehouse_locations (
warehouse_id INT PRIMARY KEY,
location coordinate
);
Kompozit qiymatni shakllantirish uchun ROW kalit so'zi va qavslardan foydalaniladi:
ROW(value1, value2, ...)
Misol:
INSERT INTO warehouse_locations (warehouse_id, location)
VALUES (1, ROW(37.318686, -121.871019))
RETURNING *;
Natija:
warehouse_id | location
--------------+-------------------------
1 | (37.318686,-121.871019)
Shuningdek, nuqta belgisi (composite_column.field_name) orqali alohida maydonlarni aniq ko'rsatib ham kiritish mumkin:
INSERT INTO warehouse_locations (
warehouse_id,
location.latitude,
location.longitude
)
VALUES (2, 37.650972, -122.398659)
RETURNING *;
Kompozit ustunning ichki maydonini o'qish uchun ustun nomini albatta qavs ichiga olish kerak:
(composite_column).field_name
[!IMPORTANT] Agar qavslar qo'yilmasa (
location.latitude), PostgreSQLlocationso'zini jadval nomi deb o'ylab, xatolik berishi mumkin.
Misol:
SELECT
warehouse_id,
(location).latitude,
(location).longitude
FROM
warehouse_locations;
Natija:
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:
SELECT
warehouse_id,
(location).*
FROM
warehouse_locations;
Alohida bitta maydonni yangilashda SET bandida qavssiz nuqta sintaksisi ishlatiladi:
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:
UPDATE warehouse_locations
SET
location = ROW(37.650971, -122.398658)
WHERE
warehouse_id = 1
RETURNING *;
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:
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:
ALTER TABLE warehouse_locations
ALTER COLUMN location TYPE coordinate_domain;
Endi ichki maydonlarga NULL kiritishga urinilsa:
INSERT INTO warehouse_locations (warehouse_id, location)
VALUES (3, ROW(NULL, NULL));
PostgreSQL qat'iy cheklov bilan to'xtatadi:
ERROR: value for domain coordinate_domain violates check constraint "coordinate_domain_check"
Composite Types) bog'liq bir nechta qiymatlarni bitta ustunda ixcham saqlash imkonini beradi.ROW(val1, val2) yordamida yoziladi.(location).latitude.CREATE DOMAIN dan foydalaniladi.