Giao diện
Soft delete & lưu trữ
Soft delete là đánh dấu một dòng đã xoá thay vì xoá thật, để khôi phục được, giữ lịch sử, hoặc không làm gãy tham chiếu.
Các cách làm
| Cách | Ví dụ | Hợp khi |
|---|---|---|
| Cột thời điểm xoá | deleted_at TIMESTAMP NULL | Cần khôi phục, cần biết xoá lúc nào |
| Trạng thái | status = 'archived' | “Xoá” thực ra là một bước trong vòng đời |
| Chuyển sang bảng lưu trữ | INSERT INTO orders_archive SELECT …; DELETE … | Bảng chính chỉ nên chứa dữ liệu đang dùng |
| Xoá thật + bảng lịch sử / CDC | Xoá khỏi bảng, giá trị cuối nằm trong history | Cần sạch bảng chính nhưng vẫn truy vết được |
Cái giá của cột deleted_at
- Mọi query phải nhớ thêm
deleted_at IS NULL. Quên một chỗ là lộ dữ liệu đã xoá. ORM có global scope / default filter để giảm rủi ro, nhưng query viết tay vẫn dễ sót. - UNIQUE bị phá: email đã xoá vẫn chặn người dùng đăng ký lại.
- PostgreSQL: partial unique index
CREATE UNIQUE INDEX ON users (email) WHERE deleted_at IS NULL. - MySQL (không có partial index): UNIQUE trên cột sinh
active_email AS (IF(deleted_at IS NULL, email, NULL)), dựa vào việc UNIQUE cho phép nhiều NULL (MySQL chương 4).
- PostgreSQL: partial unique index
- Khoá ngoại vẫn trỏ vào dòng “đã xoá”: đơn hàng của khách đã xoá vẫn hợp lệ trong mắt database. Thường đó lại là điều mong muốn (giữ lịch sử đơn), nhưng phải quyết định rõ.
- Bảng và index phình mãi vì dòng không bao giờ thật sự biến mất. Index nên có
deleted_atở cuối hoặc dùng partial index để dòng đã xoá không làm chậm query thường.
Xoá theo yêu cầu người dùng (GDPR, Nghị định 13)
Soft delete không phải là xoá dữ liệu cá nhân. Khi người dùng yêu cầu xoá, phải xoá thật hoặc ẩn danh hoá (thay tên, email, số điện thoại bằng giá trị vô nghĩa) ở bảng chính, bảng lịch sử, backup có thời hạn lưu, và các hệ thống nhận dữ liệu qua CDC. Thiết kế từ đầu một danh sách “dữ liệu cá nhân nằm ở đâu” để làm được việc này.
Ghi nhớ
deleted_atdễ làm nhưng mọi query phải lọc; UNIQUE cần partial index (PostgreSQL) hoặc cột sinh (MySQL).- Dữ liệu cũ ít dùng thì chuyển sang bảng lưu trữ.
- Soft delete không đáp ứng yêu cầu xoá dữ liệu cá nhân.