PostgreSQL / Мэдээлэл устгах (DELETE)

Мэдээлэл устгах (DELETE)

DELETE нь хүснэгтээс бичлэг бүрмөсөн устгадаг команд юм. Энгийн харагдаж болох ч буруу ашиглавал тэр даруй сэргээх боломжгүй мэдээлэл алдагдана. Тиймээс DELETE-г болгоомжтой, зөв аргачлалтай ашиглах нь маш чухал.

Үндсэн DELETE хэлбэр

sql
DELETE FROM хүснэгт
WHERE нөхцөл;

Чухал дүрэм: UPDATE-тэй адилаар WHERE мартвал хүснэгтийн БҮГД бичлэг устна. Энэ нь буцаах боломжгүй!

sql
-- Нэг бичлэг устгах
DELETE FROM users WHERE id = 5;

-- Тодорхой нөхцөлтэй устгах
DELETE FROM posts WHERE харагдсан = 0;

DELETE хийхээс өмнө SELECT хийх

Бодит системд DELETE хийхээс өмнө яг хэдэн бичлэг устгагдахыг SELECT-ээр шалгах нь заавал мөрдөх дадал:

sql
-- Эхлээд шалгана
SELECT id, нэр, үүсгэсэн
FROM users
WHERE статус = 'устгагдсан'
  AND үүсгэсэн < NOW() - INTERVAL '1 year';

-- Зөв бичлэгүүд харагдвал устгана
DELETE FROM users
WHERE статус = 'устгагдсан'
  AND үүсгэсэн < NOW() - INTERVAL '1 year';

RETURNING — устгасан бичлэгийг авах

DELETE-д ч RETURNING ашиглаж устгагдсан бичлэгийн утгуудыг авч болно. Log бичих, хэрэглэгчид харуулах зэрэгт хэрэглэнэ:

sql
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

sql
-- 30 хоногоос өмнөх уншигдсан мэдэгдлүүд устгах
DELETE FROM notifications
WHERE уншсан = TRUE
  AND үүсгэсэн < NOW() - INTERVAL '30 days';

-- Нөөц нь тэг буюу идэвхгүй бараа устгах
DELETE FROM products
WHERE нөөц <= 0
  AND идэвхтэй = FALSE
  AND ангилал = 'архив';

DELETE ... USING — өөр хүснэгтийн мэдээлэл ашиглах

Өөр хүснэгтийн нөхцөл дээр тулгуурлан устгахад USING ашиглана:

sql
-- Хаагдсан хэрэглэгчдийн нийтлэлүүдийг устгах
DELETE FROM posts
USING users
WHERE posts.user_id = users.id
  AND users.статус = 'хаагдсан';

TRUNCATE — бүгдийг хурдан цэвэрлэх

Хүснэгтийн бүх бичлэгийг устгахад DELETE FROM хүснэгт ажиллах боловч маш удаан байдаг. TRUNCATE хамаагүй хурдан:

sql
-- Бүх бичлэгийг устгах (удаан)
DELETE FROM logs;

-- Бүх бичлэгийг устгах (хурдан)
TRUNCATE TABLE logs;

-- SERIAL дугаарыг ч дахин тэгнээс эхлүүлэх
TRUNCATE TABLE logs RESTART IDENTITY;

TRUNCATE нь WHERE нөхцөл хүлээж авдаггүй — бүгдийг устгана. Туршилтын мэдээллийг цэвэрлэхэд хэрэгтэй.

CASCADE — холбоотой бичлэгүүдийг хамт устгах

Foreign key холбоотой хүснэгтүүд байхад эх бичлэгийг устгахыг оролдвол алдаа гарна:

sql
-- 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 тавьсан бол холбоотой бичлэгүүд автоматаар устгагдана:

sql
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 — аюулгүй устгах арга

Бодит системд бичлэгийг бүрмөсөн устгахын оронд "устгасан" гэж тэмдэглэх арга өргөн хэрэглэгддэг:

sql
-- Хүснэгтэд устгасан_огноо багана нэмэх
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 зэрэг хязгаарлалтуудыг сурч — мэдээллийн бүрэн бүтэн байдлыг хэрхэн хамгаалахыг ойлгоно.