Мэдээлэл устгах (DELETE)
DELETE нь хүснэгтээс бичлэг бүрмөсөн устгадаг команд юм. Энгийн харагдаж болох ч буруу ашиглавал тэр даруй сэргээх боломжгүй мэдээлэл алдагдана. Тиймээс DELETE-г болгоомжтой, зөв аргачлалтай ашиглах нь маш чухал.
Үндсэн DELETE хэлбэр
DELETE FROM хүснэгт
WHERE нөхцөл;
Чухал дүрэм: UPDATE-тэй адилаар WHERE мартвал хүснэгтийн БҮГД бичлэг устна. Энэ нь буцаах боломжгүй!
-- Нэг бичлэг устгах
DELETE FROM users WHERE id = 5;
-- Тодорхой нөхцөлтэй устгах
DELETE FROM posts WHERE харагдсан = 0;
DELETE хийхээс өмнө SELECT хийх
Бодит системд DELETE хийхээс өмнө яг хэдэн бичлэг устгагдахыг SELECT-ээр шалгах нь заавал мөрдөх дадал:
-- Эхлээд шалгана
SELECT id, нэр, үүсгэсэн
FROM users
WHERE статус = 'устгагдсан'
AND үүсгэсэн < NOW() - INTERVAL '1 year';
-- Зөв бичлэгүүд харагдвал устгана
DELETE FROM users
WHERE статус = 'устгагдсан'
AND үүсгэсэн < NOW() - INTERVAL '1 year';
RETURNING — устгасан бичлэгийг авах
DELETE-д ч RETURNING ашиглаж устгагдсан бичлэгийн утгуудыг авч болно. Log бичих, хэрэглэгчид харуулах зэрэгт хэрэглэнэ:
DELETE FROM notifications
WHERE user_id = 1 AND уншсан = TRUE
RETURNING id, гарчиг, үүсгэсэн;
id | гарчиг | үүсгэсэн
----+-----------------------+----------------------------
3 | Шинэ дагагч | 2024-03-10 08:15:00
7 | Таны нийтлэлд лайк | 2024-03-12 14:22:00
Олон нөхцөлтэй DELETE
-- 30 хоногоос өмнөх уншигдсан мэдэгдлүүд устгах
DELETE FROM notifications
WHERE уншсан = TRUE
AND үүсгэсэн < NOW() - INTERVAL '30 days';
-- Нөөц нь тэг буюу идэвхгүй бараа устгах
DELETE FROM products
WHERE нөөц <= 0
AND идэвхтэй = FALSE
AND ангилал = 'архив';
DELETE ... USING — өөр хүснэгтийн мэдээлэл ашиглах
Өөр хүснэгтийн нөхцөл дээр тулгуурлан устгахад USING ашиглана:
-- Хаагдсан хэрэглэгчдийн нийтлэлүүдийг устгах
DELETE FROM posts
USING users
WHERE posts.user_id = users.id
AND users.статус = 'хаагдсан';
TRUNCATE — бүгдийг хурдан цэвэрлэх
Хүснэгтийн бүх бичлэгийг устгахад DELETE FROM хүснэгт ажиллах боловч маш удаан байдаг. TRUNCATE хамаагүй хурдан:
-- Бүх бичлэгийг устгах (удаан)
DELETE FROM logs;
-- Бүх бичлэгийг устгах (хурдан)
TRUNCATE TABLE logs;
-- SERIAL дугаарыг ч дахин тэгнээс эхлүүлэх
TRUNCATE TABLE logs RESTART IDENTITY;
TRUNCATE нь WHERE нөхцөл хүлээж авдаггүй — бүгдийг устгана. Туршилтын мэдээллийг цэвэрлэхэд хэрэгтэй.
CASCADE — холбоотой бичлэгүүдийг хамт устгах
Foreign key холбоотой хүснэгтүүд байхад эх бичлэгийг устгахыг оролдвол алдаа гарна:
-- authors хүснэгтэд posts нь REFERENCES authors(id) байвал:
DELETE FROM authors WHERE id = 1;
-- ERROR: update or delete on table "authors" violates foreign key constraint
-- on table "posts"
Хүснэгт үүсгэхдээ ON DELETE CASCADE тавьсан бол холбоотой бичлэгүүд автоматаар устгагдана:
CREATE TABLE posts (
id BIGSERIAL PRIMARY KEY,
гарчиг TEXT NOT NULL,
author_id INTEGER REFERENCES authors(id) ON DELETE CASCADE
);
-- Одоо author устгахад түүний бүх posts ч устна
DELETE FROM authors WHERE id = 1;
ON DELETE CASCADE ашиглахдаа болгоомжтой — хүлээгдээгүй их мэдээлэл устаж болно.
Soft delete — аюулгүй устгах арга
Бодит системд бичлэгийг бүрмөсөн устгахын оронд "устгасан" гэж тэмдэглэх арга өргөн хэрэглэгддэг:
-- Хүснэгтэд устгасан_огноо багана нэмэх
ALTER TABLE users ADD COLUMN устгасан_огноо TIMESTAMPTZ;
-- "Устгах" — бүрмөсөн устгахгүй, тэмдэглэнэ
UPDATE users
SET устгасан_огноо = NOW()
WHERE id = 5;
-- Устгагдаагүй хэрэглэгчдийг унших
SELECT * FROM users WHERE устгасан_огноо IS NULL;
-- Шаардлагатай бол сэргээх боломжтой
UPDATE users
SET устгасан_огноо = NULL
WHERE id = 5;
Soft delete нь мэдээлэл алдахаас сэргийлдэг, аудит хийхэд тохиромжтой.
Дараагийн хичээлд:
PRIMARY KEY, UNIQUE, NOT NULL, CHECK зэрэг хязгаарлалтуудыг сурч — мэдээллийн бүрэн бүтэн байдлыг хэрхэн хамгаалахыг ойлгоно.