92 / 100

ENUM

Sanash ma'lumot turi

Ushbu qo'llanmada PostgreSQLda ustunga faqat belgilangan qat'iy ro'yxatdagi qiymatlarni kiritishni cheklash uchun ENUM (sanash) ma'lumot turidan qanday foydalanishni o'rganasiz.

PostgreSQL ENUM ma'lumot turiga kirish

ENUM (enumerated type) — bu oldindan e'lon qilingan statik qiymatlar ro'yxatidan iborat ma'lumot turidir.

ENUM yaratish sintaksisi:

query.sql
CREATE TYPE enum_name AS ENUM ('value1', 'value2', 'value3');

Sintaksis tushuntirishi:

  • enum_name — yaratilayotgan sanash turining nomi.
  • ('value1', 'value2', ...) — ruxsat etilgan qiymatlar ro'yxati.
  • Qiymatlar tartiblangan bo'ladi: ro'yxatda birinchi kelgan qiymat keyingi qiymatdan kichik deb hisoblanadi.

Namunaviy jadval

Avval buyurtma ustuvorligini ifodalovchi priority_type turini yaratamiz:

query.sql
DROP TYPE IF EXISTS priority_type CASCADE;

CREATE TYPE priority_type AS ENUM ('low', 'medium', 'high');

Endi undan jadval ustunida foydalanamiz:

query.sql
DROP TABLE IF EXISTS transfer_orders CASCADE;

CREATE TABLE transfer_orders (
  id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  product_id INT NOT NULL,
  from_warehouse INT NOT NULL,
  to_warehouse INT NOT NULL,
  quantity INT CHECK (quantity > 0),
  priority priority_type NOT NULL DEFAULT 'medium'
);

Ma'lumotlarni kiritish va tekshirish

Jadvalga bir nechta buyurtma kiritamiz:

query.sql
INSERT INTO transfer_orders (product_id, from_warehouse, to_warehouse, quantity, priority)
VALUES
  (1, 1, 2, 50, 'high'),
  (2, 2, 1, 20, 'low'),
  (2, 2, 1, 20, 'medium'),
  (3, 1, 2, 30, 'high');

Agar ro'yxatda mavjud bo'lmagan qiymat kiritilsa:

query.sql
INSERT INTO transfer_orders (product_id, from_warehouse, to_warehouse, quantity, priority)
VALUES (4, 1, 2, 10, 'critical');

PostgreSQL xatolik chiqaradi:

matn
ERROR:  invalid input value for enum priority_type: "critical"

ENUM bo'yicha saralash va filtrlash

ENUM qiymatlari yaratilish paytidagi tartib bo'yicha taqqoslanadi ('low' < 'medium' < 'high'):

query.sql
SELECT product_id, quantity, priority
FROM transfer_orders
ORDER BY priority DESC;

Natija:

matn
 product_id | quantity | priority 
------------+----------+----------
          1 |       50 | high
          3 |       30 | high
          2 |       20 | medium
          2 |       20 | low

High ustuvorlikdagi buyurtmalarni filtrlash:

query.sql
SELECT product_id, quantity, priority
FROM transfer_orders
WHERE priority = 'high';

ENUM turini o'zgartirish (ALTER TYPE)

1) Yangi qiymat qo'shish

Mavjud priority_type ga yangi 'urgent' qiymatini qo'shish:

query.sql
ALTER TYPE priority_type
ADD VALUE 'urgent';

Yangi qiymatni boshqa qiymatdan oldin yoki keyin joylashtirish mumkin:

query.sql
ALTER TYPE priority_type
ADD VALUE 'critical' BEFORE 'high';

2) Qiymat nomini o'zgartirish (RENAME VALUE)

PostgreSQL 10 dan boshlab enum qiymatini qayta nomlash mumkin:

query.sql
ALTER TYPE priority_type
RENAME VALUE 'urgent' TO 'very high';

3) Barcha enum qiymatlarini ko'rish (ENUM_RANGE)

query.sql
SELECT ENUM_RANGE(NULL::priority_type) AS all_priorities;

Natija:

matn
              all_priorities              
------------------------------------------
 {low,medium,critical,high,"very high"}

ENUM va Bog'langan jadval (Lookup Table / Foreign Key)

Qachon qaysi birini ishlatish kerak?

  • ENUM: Qiymatlar ro'yxati kam o'zgaradigan va oldindan aniq bo'lgan holatlarda (masalan, haftaning kunlari, jins, holatlar: 'draft', 'published', 'archived'). ENUM juda ixcham (bazada 4 bayt) va tez ishlaydi.
  • Lookup jadval + Foreign Key: Qiymatlar tez-tez foydalanuvchilar yoki administratorlar tomonidan qo'shiladigan, o'chiriladigan yoki qo'shimcha maydonlarga ega bo'lgan holatlarda (masalan, tovar toifalari, mamlakatlar, dinamik statuslar).

Xulosa

  • ENUM ustun qiymatlarini belgilangan qat'iy ro'yxat bilan cheklaydi.
  • CREATE TYPE ... AS ENUM orqali yangi enum turi yaratiladi.
  • ALTER TYPE ... ADD VALUE yangi qiymatlar qo'shish imkonini beradi.
  • ENUM qiymatlari ichki tartibga ega bo'lib, saralashda qulaylik yaratadi.