9-bo‘lim

UPDATE va DELETE

Ma'lumotni o'zgartirish va o'chirish, WHERE ning muhimligi, xavfsizlik qoidalari va yumshoq o'chirish.

🕑 16 daqiqa o‘qish 📄 613 so‘z 👁 6 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. UPDATE
  2. Bir nechta ustunni birga
  3. Mavjud qiymatdan foydalanish
  4. WHERE siz UPDATE - eng xavfli xato
  5. Himoyalanish usullari
  6. Shartli yangilash
  7. Boshqa jadvaldan yangilash
  8. DELETE
  9. DELETE, TRUNCATE, DROP
  10. Yumshoq o'chirish (soft delete)
  11. Ehtiyot choralari ro'yxati
  12. Amaliy misollar
  13. ROW_COUNT()
  14. Xulosa

Ma'lumot qo'shishni va o'qishni bilamiz. Endi uni o'zgartirish va o'chirishni o'rganamiz - bu eng xavfli ikki buyruq.

UPDATE #

SQL
UPDATE jadval
SET ustun1 = qiymat1, ustun2 = qiymat2
WHERE shart;
SQL
-- Bitta talabaning bahosini yangilash
UPDATE talabalar
SET ortacha_baho = 4.75
WHERE id = 3;
Natija
Query OK, 1 row affected (0.003 sec)
Rows matched: 1  Changed: 1  Warnings: 0

Bir nechta ustunni birga #

SQL
UPDATE talabalar
SET
    telefon = '+998901112233',
    shahar  = 'Toshkent',
    yangilangan = NOW()
WHERE id = 5;

Mavjud qiymatdan foydalanish #

SQL
-- Barcha baholarni 0.1 ga oshirish
UPDATE talabalar
SET ortacha_baho = ortacha_baho + 0.1
WHERE ortacha_baho < 4.9;

-- Narxlarni 15% ga oshirish
UPDATE mahsulotlar
SET narx = ROUND(narx * 1.15)
WHERE kategoriya = 'elektronika';

-- Hisoblagichni oshirish
UPDATE maqolalar
SET korishlar = korishlar + 1
WHERE id = 42;

WHERE siz UPDATE - eng xavfli xato #

WHERE ni unutish barcha qatorlarni o'zgartiradi
SQL
-- FALOKAT: butun jadvaldagi hamma talabaning bahosi 5.0 bo'ladi
UPDATE talabalar SET ortacha_baho = 5.0;
Natija
Query OK, 8 rows affected

Bu xatoni qaytarib bo'lmaydi (agar tranzaksiya ichida bo'lmasa). Bir necha soniyada butun bazani buzish mumkin.

Himoyalanish usullari #

1. Avval SELECT bilan tekshiring

SQL
-- Avval: nima o'zgaradi?
SELECT id, ism, ortacha_baho FROM talabalar WHERE shahar = 'Toshkent';

-- Natija to'g'ri bo'lsa, keyin:
UPDATE talabalar SET ortacha_baho = ortacha_baho + 0.2 WHERE shahar = 'Toshkent';

2. Xavfsiz rejimni yoqing

SQL
SET SQL_SAFE_UPDATES = 1;

UPDATE talabalar SET ortacha_baho = 5.0;
Natija
ERROR 1175 (HY000): You are using safe update mode and you tried to
update a table without a WHERE that uses a KEY column
SQL_SAFE_UPDATES ni yoqib qo'ying

Bu rejim WHERE da kalit ustun (id yoki indeksli ustun) bo'lmagan UPDATE/DELETE larni bloklaydi.

MySQL Workbench da u sukut bo'yicha yoqilgan. Konsolda esa qo'lda yoqish kerak:

SQL
SET SQL_SAFE_UPDATES = 1;

Har bir sessiyada qayta yoqiladi. Ishlab chiqarish serverida ishlaganda - majburiy odat.

3. LIMIT bilan cheklang

SQL
UPDATE talabalar
SET ortacha_baho = 4.5
WHERE shahar = 'Toshkent'
LIMIT 1;

4. Tranzaksiya ichida bajaring

SQL
START TRANSACTION;

UPDATE talabalar SET ortacha_baho = ortacha_baho + 0.5;

SELECT ism, ortacha_baho FROM talabalar;    -- tekshiramiz

ROLLBACK;    -- yoqmasa bekor qilamiz
-- yoki
COMMIT;      -- to'g'ri bo'lsa tasdiqlaymiz

16-bo'limda tranzaksiyalarni batafsil ko'ramiz.

Shartli yangilash #

SQL
-- CASE bilan
UPDATE talabalar
SET daraja = CASE
    WHEN ortacha_baho >= 4.5 THEN 'alochi'
    WHEN ortacha_baho >= 3.5 THEN 'yaxshi'
    ELSE 'oddiy'
END;

-- Bir nechta qatorni har xil qiymat bilan
UPDATE mahsulotlar
SET narx = CASE id
    WHEN 1 THEN 185000
    WHEN 2 THEN  95000
    WHEN 3 THEN 2450000
END
WHERE id IN (1, 2, 3);

Boshqa jadvaldan yangilash #

SQL
-- JOIN bilan (11-bo'limda batafsil)
UPDATE talabalar t
JOIN guruhlar g ON g.id = t.guruh_id
SET t.faolmi = FALSE
WHERE g.yil < 2025;

-- Ichki so'rov bilan
UPDATE guruhlar g
SET talabalar_soni = (
    SELECT COUNT(*) FROM talabalar t WHERE t.guruh_id = g.id
);

DELETE #

SQL
DELETE FROM jadval WHERE shart;
SQL
-- Bitta qatorni o'chirish
DELETE FROM talabalar WHERE id = 8;

-- Shart bo'yicha
DELETE FROM talabalar WHERE faolmi = FALSE;

-- Eski yozuvlarni tozalash
DELETE FROM loglar WHERE yaratilgan < DATE_SUB(NOW(), INTERVAL 90 DAY);

-- Cheklov bilan
DELETE FROM loglar
WHERE yaratilgan < '2025-01-01'
ORDER BY yaratilgan
LIMIT 1000;
DELETE WHERE siz butun jadvalni tozalaydi
SQL
DELETE FROM talabalar;      -- HAMMA MA'LUMOT YO'QOLADI

UPDATE bilan bir xil qoidalar amal qiladi: avval SELECT, xavfsiz rejim, LIMIT va tranzaksiya.

DELETE, TRUNCATE, DROP #

BuyruqNima qiladiTezlikQaytarish
DELETE FROM t WHERE ...Tanlangan qatorlarSekinTranzaksiyada mumkin
DELETE FROM tBarcha qatorlarSekinTranzaksiyada mumkin
TRUNCATE TABLE tBarcha qatorlarJuda tezMumkin emas
DROP TABLE tJadvalning o'ziTezMumkin emas
SQL
DELETE FROM talabalar;        -- qatorlar o'chadi, AUTO_INCREMENT saqlanadi
TRUNCATE TABLE talabalar;     -- qatorlar o'chadi, AUTO_INCREMENT 1 ga qaytadi
DROP TABLE talabalar;         -- jadval umuman yo'qoladi
TRUNCATE tranzaksiyani tan olmaydi
SQL
START TRANSACTION;
TRUNCATE TABLE talabalar;
ROLLBACK;                     -- ISHLAMAYDI, ma'lumot qaytmaydi

TRUNCATE - DDL buyrug'i va u avtomatik COMMIT qiladi. Uni faqat ma'lumot rostdan ham kerak emasligiga ishonch hosil qilgandan keyin ishlating.

Yumshoq o'chirish (soft delete) #

Amalda ma'lumotni butunlay o'chirish kamdan-kam to'g'ri yechim bo'ladi:

SQL
-- Jadvalga ustun qo'shamiz
ALTER TABLE talabalar ADD COLUMN ochirilgan_sana DATETIME NULL DEFAULT NULL;

-- "O'chirish" - aslida belgilash
UPDATE talabalar SET ochirilgan_sana = NOW() WHERE id = 5;

-- Faol yozuvlarni olish
SELECT * FROM talabalar WHERE ochirilgan_sana IS NULL;

-- Tiklash
UPDATE talabalar SET ochirilgan_sana = NULL WHERE id = 5;
Yumshoq o'chirishning afzalliklari
AfzallikIzoh
Tiklash mumkinFoydalanuvchi adashsa qaytariladi
Tarix saqlanadiKim, qachon o'chirgani ma'lum
Bog'lanishlar buzilmaydiEski buyurtmalarda mijoz nomi qoladi
Hisobotlar to'g'riO'tgan oy statistikasi o'zgarmaydi

Kamchiligi: jadval o'sib boradi va har bir so'rovga WHERE ochirilgan_sana IS NULL qo'shish kerak.

Bu naqsh Laravel, Django va boshqa freymvorklarda tayyor holda mavjud.

Ehtiyot choralari ro'yxati #

Ishlab chiqarish serverida ishlashdan oldin
  1. Zaxira nusxa oling - mysqldump bilan (19-bo'lim)
  2. SELECT bilan tekshiring - qancha qator o'zgaradi?
  3. SQL_SAFE_UPDATES yoqing
  4. Tranzaksiya ichida bajaring - START TRANSACTION ... ROLLBACK/COMMIT
  5. Sinov bazasida sinang - imkoni bo'lsa
  6. Ish vaqtidan tashqarida - katta o'zgarishlarni tunda qiling
  7. LIMIT qo'ying - katta jadvalda qismlarga bo'lib bajaring

Bu ro'yxatga rioya qilish sizni bir kun katta muammodan qutqaradi.

Amaliy misollar #

SQL
-- 1. Faol bo'lmagan talabalarni arxivga ko'chirish va o'chirish
START TRANSACTION;

INSERT INTO talabalar_arxiv (ism, familiya, email, shahar, arxivlangan)
SELECT ism, familiya, email, shahar, NOW()
FROM talabalar
WHERE faolmi = FALSE;

DELETE FROM talabalar WHERE faolmi = FALSE;

COMMIT;
SQL
-- 2. Takrorlanuvchi email larni tozalash (eng eskisini qoldirib)
DELETE t1 FROM talabalar t1
JOIN talabalar t2
  ON t1.email = t2.email AND t1.id > t2.id;
SQL
-- 3. Guruh statistikasini yangilash
UPDATE guruhlar g
SET
    talabalar_soni = (SELECT COUNT(*) FROM talabalar t WHERE t.guruh_id = g.id),
    ortacha_baho   = (SELECT ROUND(AVG(ortacha_baho), 2) FROM talabalar t WHERE t.guruh_id = g.id);
SQL
-- 4. Narxlarni kategoriya bo'yicha turlicha o'zgartirish
UPDATE mahsulotlar
SET narx = ROUND(
    narx * CASE kategoriya
        WHEN 'elektronika' THEN 1.10
        WHEN 'kiyim'       THEN 1.05
        ELSE 1.00
    END
)
WHERE faolmi = TRUE;
SQL
-- 5. Eski loglarni bo'lib-bo'lib o'chirish (katta jadval uchun)
DELETE FROM loglar
WHERE yaratilgan < DATE_SUB(NOW(), INTERVAL 1 YEAR)
LIMIT 10000;
-- Bu so'rovni ROW_COUNT() = 0 bo'lguncha takrorlash kerak
Katta jadvalni qismlarga bo'lib o'chirish

Bir vaqtda million qator o'chirish jadvalni uzoq vaqt bloklaydi va tranzaksiya jurnalini to'ldiradi. LIMIT 10000 bilan bo'lib bajarish ancha xavfsiz - boshqa so'rovlar orasida nafas olish imkoni qoladi.

ROW_COUNT() #

SQL
UPDATE talabalar SET faolmi = FALSE WHERE ortacha_baho < 3.0;
SELECT ROW_COUNT() AS ozgargan_qatorlar;
Natija
+-------------------+
| ozgargan_qatorlar |
+-------------------+
|                 1 |
+-------------------+
Amaliy topshiriq

kutubxona bazasida:

  1. Bitta kitobning narxini yangilang (WHERE id = ...).
  2. Barcha kitoblar narxini 10% ga oshiring.
  3. CASE bilan janrga qarab turli foizda oshiring.
  4. mavjudmi ustunini qo'shing va 2000-yilgacha bo'lgan kitoblarni FALSE qiling.
  5. SQL_SAFE_UPDATES ni yoqing va WHERE siz UPDATE yozib ko'ring - xatoni ko'ring.
  6. Tranzaksiya ichida barcha narxlarni nolga tenglang, tekshiring va ROLLBACK qiling.
  7. Yumshoq o'chirish uchun ochirilgan_sana ustunini qo'shing va bitta kitobni "o'chiring".
  8. ROW_COUNT() bilan nechta qator o'zgarganini tekshiring.

Xulosa #

  • UPDATE jadval SET ustun = qiymat WHERE shart; - o'zgartirish.
  • DELETE FROM jadval WHERE shart; - o'chirish.
  • WHERE ni unutish butun jadvalni o'zgartiradi yoki o'chiradi.
  • Har doim avval SELECT bilan tekshiring.
  • SET SQL_SAFE_UPDATES = 1 ni yoqib qo'ying.
  • TRUNCATE tez, lekin qaytarib bo'lmaydi va tranzaksiyani tan olmaydi.
  • Yumshoq o'chirish (ochirilgan_sana) - amalda ko'proq to'g'ri yondashuv.
  • Katta jadvalni LIMIT bilan qismlarga bo'lib o'zgartiring.

Keyingi bo'limda jadvallar orasidagi bog'lanishlarni o'rganamiz.

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.