ALTER TABLE, DROP — ustun qo'shish, o'zgartirish, o'chirish

~15 daq · PostgreSQL · DDL va DML

Jadval yaratildi, ishga tushdi. Bir haftadan so'ng mijoz yangi talablar bilan keldi:

  • telefon ustuni kerak ekan — o'ylanmagan
  • ism ustuni VARCHAR(50) qilib yaratilgan, lekin ba'zi ismlar sig'mayapti
  • vaqtinchalik_maydon deb yaratilgan ustun endi keraksiz
  • Jadval nomi noto'g'ri yozilgan

Jadvalni o'chirib qaytadan yaratish mumkin — lekin ichidagi minglab ma'lumotlar yo'qoladi. Shu sababli mavjud jadvalni ma'lumotlarga tegmay o'zgartirish kerak. Buning uchun ALTER TABLE ishlatiladi.


ALTER TABLE nima?

ALTER TABLE — ishlab turgan jadvalni to'xtatmasdan, ma'lumotlarni yo'qotmasdan tuzilmasini o'zgartirish buyrug'i.

Hayotiy o'xshatma

Uy ta'miri. Oilani boshqa joyga ko'chirib, keyin uyni buzib qaytadan qurmaysiz. Jihozlarni saqlab, faqat devorni o'zgartirasiz, yangi xona qo'shasiz, keraksiz bo'lgan qismni buzasiz. ALTER TABLE ham xuddi shunday — ma'lumotlar o'rnida qoladi, faqat jadval tuzilmasi o'zgaradi.


Ustun qo'shish — ADD COLUMN

Yangi ustun qo'shilganda mavjud qatorlardagi shu ustun qiymati NULL bo'ladi — chunki ular yaratilganida bu ustun yo'q edi.

ALTER TABLE foydalanuvchilar
ADD COLUMN telefon VARCHAR(20);

Bir vaqtda bir nechta ustun qo'shish mumkin:

ALTER TABLE foydalanuvchilar
ADD COLUMN telefon    VARCHAR(20),
ADD COLUMN manzil     TEXT,
ADD_ilgan  DATE;

NOT NULL bilan ustun qo'shilmoqchi bo'lsangiz — muammo chiqadi. Mavjud qatorlarda bu ustun uchun qiymat yo'q, ya'ni NULL. Lekin NOT NULL deyapiz — ziddiyat. Shu sababli DEFAULT ham birga yoziladi: mavjud qatorlar shu standart qiymatni oladi:

-- ❌ — mavjud qatorlarda NULL bo'ladi, NOT NULL buziladi
ALTER TABLE foydalanuvchilar ADD COLUMN faol BOOLEAN NOT NULL;

-- ✅ — mavjud qatorlar DEFAULT qiymatni oladi
ALTER TABLE foydalanuvchilar ADD COLUMN faol BOOLEAN NOT NULL DEFAULT TRUE;

Ustun turini o'zgartirish — ALTER COLUMN TYPE

Maydon turi noto'g'ri tanlangan bo'lsa o'zgartiriladi. Kichik turdan kattasiga o'tish muammosiz — son sigadi:

-- INTEGER dan BIGINT ga — xavfsiz, son kattaroq joyga ko'chadi
ALTER TABLE mahsulotlar
ALTER COLUMN ko'rishlar TYPE BIGINT;

-- VARCHAR(50) dan TEXT ga — xavfsiz, matn uzaydi
ALTER TABLE foydalanuvchilar
ALTER COLUMN ism TYPE TEXT;

Lekin TEXT dan INTEGER ga o'tish murakkab — matn soni bo'lmasligi mumkin. PostgreSQL buni o'zi hal qilolmaydi, qanday o'girish kerakligini ko'rsatish shart. Buning uchun USING:

ALTER TABLE test
ALTER COLUMN yosh TYPE INTEGER USING yosh::INTEGER;
--                              ↑ "matnni INTEGER ga o'gir" degani

yosh ustunida "25", "30" kabi raqam ko'rinishidagi matnlar bo'lsa — muammosiz o'tadi. Lekin "yigirma besh" kabi matn bo'lsa — xato chiqadi.


Ustun nomini o'zgartirish — RENAME COLUMN

ALTER TABLE foydalanuvchilar
RENAME COLUMN ism TO toʻliq_ism;

Bu faqat nom o'zgaradi — ma'lumotlar, indekslar, constraintlar o'z joyida qoladi.


NOT NULL qo'shish

Avval ixtiyoriy bo'lgan ustunni majburiy qilish kerak bo'lsa — SET NOT NULL ishlatiladi. Lekin bu xavfli qadam: agar jadvalda NULL qiymatlar bo'lsa, PostgreSQL qo'ymaydi.

Shu sababli uch bosqichda qilinadi:

-- 1. NULL lar bormi tekshiring
SELECT COUNT(*) FROM foydalanuvchilar WHERE telefon IS NULL;

-- 2. NULL larni to'ldiring
UPDATE foydalanuvchilar SET telefon = 'nomaʼlum' WHERE telefon IS NULL;

-- 3. Endi NOT NULL qo'shing
ALTER TABLE foydalanuvchilar
ALTER COLUMN telefon SET NOT NULL;

Orqaga qaytarish — NOT NULL olib tashlash:

ALTER TABLE foydalanuvchilar
ALTER COLUMN telefon DROP NOT NULL;

DEFAULT qo'shish va olib tashlash

Mavjud ustunга standart qiymat qo'shish yoki o'chirish:

ALTER TABLE foydalanuvchilar
ALTER COLUMN rol SET DEFAULT 'user';

ALTER TABLE foydalanuvchilar
ALTER COLUMN rol DROP DEFAULT;

Ustun o'chirish — DROP COLUMN

Keraksiz ustunni o'chirish:

ALTER TABLE foydalanuvchilar
DROP COLUMN manzil;

O'chirilgan ustundagi barcha ma'lumotlar ham yo'qoladi — qaytarib bo'lmaydi. Shu sababli o'chirishdan oldin kerakmi-yo'qmi ekanligini aniq tekshiring.

Bir vaqtda bir nechta:

ALTER TABLE foydalanuvchilar
DROP COLUMN manzil,
DROP COLUMN vaqtinchalik_maydon;

Jadval nomini o'zgartirish

ALTER TABLE foydalanuvchilar
RENAME TO users;

Jadval o'chirish — DROP TABLE

DROP TABLE — jadvalni butunlay o'chiradi. Tuzilma ham, barcha ma'lumotlar ham yo'qoladi.

DROP TABLE foydalanuvchilar;

-- Jadval yo'q bo'lsa xato bermasin
DROP TABLE IF EXISTS foydalanuvchilar;

buyurtmalar jadvali foydalanuvchilar ga bog'liq bo'lsa — PostgreSQL o'chirishga ruxsat bermaydi. Chunki bog'liq ma'lumotlar "yetim" qoladi. Avval buyurtmalar o'chiriladi, keyin foydalanuvchilar:

DROP TABLE buyurtmalar;
DROP TABLE foydalanuvchilar;

-- Yoki barcha bog'liq jadvallar bilan birga:
DROP TABLE foydalanuvchilar CASCADE;  -- ⚠️ buyurtmalar ham o'chadi

psql da ko'rish

\dt               — jadvallar ro'yxati
\d jadval_nomi    — jadval tuzilmasi (o'zgarishlarni tekshirish uchun)

Tez-tez uchraydigan xatolar

Tur o'zgartirishda ma'lumot yo'qolishi

Katta turdan kichik turga o'tayotganda — mavjud qiymatlar sig'masligi mumkin:

-- Avval maksimal qiymatni tekshiring
SELECT MAX(koʻrishlar) FROM mahsulotlar;
-- 9,823,456,789 — bu INTEGER ga sig'maydi (maksimum: 2,147,483,647)
-- Bunday holda BIGINT da qoldiring

RENAME dan keyin eski nom ishlatilib qolishi

Ustun nomi o'zgartirildi, lekin kod yoki view larda eski nom qolgan bo'lishi mumkin. O'zgartirishdan keyin barcha so'rovlar, viewlar, funksiyalarni tekshiring.


Xulosa

ALTER TABLE — ishlab turgan jadvalni ma'lumotlarga tegmay o'zgartirish.

ADD COLUMN nom tur             — ustun qo'shish
ALTER COLUMN nom TYPE tur      — tur o'zgartirish
RENAME COLUMN eski TO yangi    — nom o'zgartirish
ALTER COLUMN nom SET NOT NULL  — majburiy qilish
ALTER COLUMN nom SET DEFAULT   — standart qiymat qo'shish
DROP COLUMN nom                — ustun o'chirish
RENAME TO yangi_nom            — jadval nomini o'zgartirish

DROP TABLE — jadvalni to'liq o'chiradi. IF EXISTS — yo'q bo'lsa xato bermasin. CASCADE — bog'liq jadvallar bilan birga o'chiradi.


Keyingi dars

8-dars: INSERT, SELECT — WHERE, AND, OR, BETWEEN, IN, LIKE, IS NULL