Skip to content

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áchVí dụHợp khi
Cột thời điểm xoádeleted_at TIMESTAMP NULLCần khôi phục, cần biết xoá lúc nào
Trạng tháistatus = '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ử / CDCXoá khỏi bảng, giá trị cuối nằm trong historyCầ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).
  • 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ớ

  1. deleted_at dễ làm nhưng mọi query phải lọc; UNIQUE cần partial index (PostgreSQL) hoặc cột sinh (MySQL).
  2. Dữ liệu cũ ít dùng thì chuyển sang bảng lưu trữ.
  3. Soft delete không đáp ứng yêu cầu xoá dữ liệu cá nhân.