Chuyển đến nội dung chính

SQL ON DELETE CASCADE: Tự động xóa dữ liệu phụ thuộc

Hiểu cách SQL ON DELETE CASCADE tự động xóa dữ liệu phụ thuộc trong SQL, giữ các bảng nhất quán và giúp ngăn mất dữ liệu ngoài ý muốn.
· 9 phút đọc

Khám phá cùng AI

Xóa dữ liệu trong SQL không chỉ là loại bỏ một hàng. Trong cơ sở dữ liệu quan hệ, các bảng thường liên kết với nhau, và thao tác xóa ở một bảng có thể ảnh hưởng đến các bảng khác. Để quản lý an toàn, SQL sử dụng ràng buộc khóa ngoại để xác định cách dữ liệu liên quan sẽ ứng xử khi các hàng bị xóa hoặc cập nhật.

Một trong những tùy chọn xóa mạnh mẽ nhất là ràng buộc SQL ON DELETE CASCADE. Thay vì chặn thao tác xóa hoặc để lại bản ghi mồ côi, quy tắc này yêu cầu cơ sở dữ liệu tự động xóa tất cả các hàng con phụ thuộc khi hàng cha được tham chiếu bị xóa.

Trong hướng dẫn này, tôi sẽ trình bày cách ràng buộc ON DELETE CASCADE hoạt động, vì sao cơ sở dữ liệu hỗ trợ xóa dây chuyền tự động, và khi nào nó là lựa chọn phù hợp so với các quy tắc hạn chế hơn như ON DELETE RESTRICT. Nếu bạn mới bắt đầu với SQL, hãy học khóa Introduction to SQL, hoặc khóa Intermediate SQL nếu bạn đã có chút kinh nghiệm. 

ON DELETE CASCADE trong SQL là gì?

Để hiểu cách ràng buộc khóa ngoại ON DELETE CASCADE hoạt động, trước hết hãy nói về toàn vẹn tham chiếu và mệnh đề CASCADE.

Toàn vẹn tham chiếu và khóa ngoại

Trong cơ sở dữ liệu quan hệ, các bảng được kết nối thông qua khóa ngoại, liên kết một cột ở bảng này (bảng con) với khóa chính ở bảng khác (bảng cha). Khóa ngoại thực thi toàn vẹn tham chiếu để đảm bảo một hàng con luôn trỏ tới một hàng cha hợp lệ. 

Nếu không có cơ chế này, cơ sở dữ liệu có thể dễ dàng xuất hiện các bản ghi mồ côi, nơi các hàng tham chiếu tới dữ liệu không còn tồn tại. Do đó, các quy tắc xóa được đặt ra để chỉ rõ cho cơ sở dữ liệu cách xử lý những trường hợp mồ côi này ngay từ trước khi chúng xảy ra.

CASCADE thực sự có nghĩa là gì

Trong SQL, ràng buộc ON DELETE CASCADE yêu cầu cơ sở dữ liệu tự động xóa tất cả các hàng con tham chiếu tới hàng cha bị xóa. Nó kích hoạt thao tác một cách đệ quy qua các chuỗi khóa ngoại, xóa dữ liệu phụ thuộc trong một giao dịch nguyên tử.

Ví dụ, bạn có thể xóa một bản ghi khách hàng trong cơ sở dữ liệu, và việc này sẽ dây chuyền xóa các đơn hàng của họ, từ đó xóa các mặt hàng trong đơn chỉ với một truy vấn.

Cách ON DELETE CASCADE vận hành trong thực tế

Giờ bạn đã hiểu CASCADE làm gì, hãy xem cơ sở dữ liệu áp dụng logic đó như thế nào.

Quan hệ giữa bảng cha và bảng con

Như bạn đã biết, trong các quan hệ của cơ sở dữ liệu, một bảng đóng vai trò bảng cha, nắm giữ khóa chính, trong khi bảng khác đóng vai trò bảng con, lưu khóa đó như một khóa ngoại. Khi bạn chạy câu lệnh DELETE trên bảng cha, bộ máy cơ sở dữ liệu trước tiên sẽ kiểm tra các ràng buộc khóa ngoại để xác định tất cả các phần tử phụ thuộc thông qua đánh chỉ mục để tăng tốc.

Điều gì xảy ra khi một hàng cha bị xóa

Khi bạn thực thi lệnh DELETE trên một hàng cha, cơ sở dữ liệu sẽ tạm dừng việc thực thi cuối cùng để kiểm tra các quy tắc khóa ngoại theo thứ tự sau:

  • Xác định: Bộ máy tra cứu chỉ mục khóa ngoại để tìm tất cả các hàng ở bảng con khớp với ID đang bị xóa.
  • Thực thi: Trước (hoặc trong khi) xóa hàng cha, bộ máy xóa các hàng con đã được xác định.
  • Xác nhận: Cơ sở dữ liệu đảm bảo không còn hàng mồ côi. Nếu mọi thao tác xóa thành công, giao dịch sẽ được hoàn tất.

Lưu ý rằng quy trình trên chỉ diễn ra nếu bạn đã định nghĩa ràng buộc ON DELETE CASCADE, như chúng ta sẽ thấy ở phần sau.

ON DELETE CASCADE so với các quy tắc xóa khác

Trong SQL, có nhiều quy tắc DELETE chỉ cho cơ sở dữ liệu cách xử lý dữ liệu liên quan giữa các bảng khác nhau. Phần này sẽ so sánh ON DELETE CASCADE với các ràng buộc đó.

CASCADE và RESTRICT

Từ phần giải thích ở trên, ta thấy CASCADE tự động xóa tất cả các hàng con phụ thuộc khi hàng cha bị loại bỏ, đảm bảo không còn bản ghi mồ côi.

Tuy nhiên, ràng buộc SQL RESTRICT sẽ chặn hoàn toàn thao tác xóa nếu vẫn còn hàng con tham chiếu tới hàng cha. Cách này giúp tránh mất dữ liệu ngoài ý muốn. Trong ví dụ dưới đây, ràng buộc RESTRICT ngăn việc xóa một khách hàng nếu còn đơn hàng tham chiếu tới khách hàng đó.

-- Parent table
CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    name VARCHAR(100)
);

-- Child table with ON DELETE RESTRICT
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE RESTRICT
);

CASCADE so với SET NULL và SET DEFAULT

Trong khi CASCADE xóa hẳn các hàng phụ thuộc, SET NULL và SET DEFAULT giữ lại các hàng con theo các cách sau:

Khi bạn định nghĩa ràng buộc là ON DELETE SET NULL, hàng cha bị xóa nhưng giá trị khóa ngoại trong bảng con được đặt thành NULL.

Trong ví dụ dưới đây, việc xóa một khách hàng không xóa các đơn hàng liên quan. Thay vào đó, cột customer_id trong bảng orders được tự động đặt về NULL. Cách này giữ lại các bản ghi đơn hàng đồng thời cắt quan hệ với khách hàng đã bị xóa.

-- Child table using ON DELETE SET NULL
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT NULL,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE SET NULL
);

Tương tự, với tùy chọn SET DEFAULT, việc xóa khách hàng không xóa các đơn hàng liên quan. Thay vào đó, customer_id trong bảng orders được đặt lại về giá trị mặc định đã định nghĩa. Điều này giữ nguyên các bản ghi đơn hàng và gán cho chúng một giá trị thay thế đã định sẵn.

-- Child table using ON DELETE SET DEFAULT
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT DEFAULT 0,
    CONSTRAINT fk_orders_customers
        FOREIGN KEY (customer_id)
        REFERENCES customers(customer_id)
        ON DELETE SET DEFAULT
);

Tạo khóa ngoại với ON DELETE CASCADE

Để sử dụng ràng buộc ON DELETE RESTRICT trong SQL, bạn phải chỉ định nó khi thiết lập quan hệ khóa ngoại giữa bảng cha và bảng con.

CASCADE trong lược đồ bảng

Bạn có thể định nghĩa quy tắc ON DELETE CASCADE trong SQL ngay khi tạo bảng hoặc bằng cách sửa đổi các bảng hiện có.

Ví dụ dưới đây cho thấy cách áp dụng ràng buộc khóa ngoại SQL ON DELETE CASCADE khi định nghĩa một bảng mới. Với CASCADE, xóa một phòng ban sẽ tự động loại bỏ tất cả nhân viên thuộc phòng ban đó.

-- Stores department details
CREATE TABLE departments (
    department_id INT PRIMARY KEY, 
    department_name VARCHAR(100)
);

-- Automatically deletes employees when their department is deleted
CREATE TABLE employees (
    employee_id INT PRIMARY KEY,      -- Unique employee identifier
    department_id INT, 
    CONSTRAINT fk_employees_departments
        FOREIGN KEY (department_id)
        REFERENCES departments(department_id)
        ON DELETE CASCADE
);

Nếu bảng đã tồn tại, bạn có thể thêm ràng buộc khóa ngoại với ON DELETE CASCADE. Như vậy, khi xóa một phòng ban, mọi bản ghi nhân viên liên quan sẽ tự động bị xóa.

-- Adds a foreign key constraint after the table already exists
ALTER TABLE employees
ADD CONSTRAINT fk_employees_departments
FOREIGN KEY (department_id)
REFERENCES departments(department_id)
ON DELETE CASCADE;    -- Deletes employees when the related department is deleted

Chuỗi dây chuyền và xóa đa cấp

Một trong những điểm mạnh của CASCADE là việc xóa không dừng ở một quan hệ duy nhất. Nếu một bảng con đồng thời là bảng cha của bảng khác, thao tác xóa có thể lan qua nhiều cấp, gọi là chuỗi dây chuyền. Ví dụ, xóa một người dùng có thể xóa các đơn hàng, từ đó xóa các mặt hàng trong đơn, rồi có thể xóa các hàng nhật ký kiểm toán liên quan.

Vì vậy, cần ghi chép và rà soát cẩn thận các lược đồ sử dụng CASCADE. Do một câu lệnh xóa có thể ảnh hưởng tới nhiều bảng, bạn nên hiểu đầy đủ chuỗi phụ thuộc trước khi bật hành vi dây chuyền.

Các trường hợp sử dụng phổ biến cho ON DELETE CASCADE

Ràng buộc ON DELETE CASCADE trong SQL quan trọng trong các tình huống mà dữ liệu ở bảng con không có giá trị nếu thiếu bản ghi ở bảng cha. Hãy xem ứng dụng của nó trong quản trị cơ sở dữ liệu thực tế.

Tự động dọn dẹp dữ liệu phụ thuộc

Bạn có thể dùng ON DELETE CASCADE để dọn dẹp dữ liệu mà nếu làm thủ công sẽ kém hiệu quả. Bao gồm các bảng như log, lịch sử, nhật ký kiểm toán, hoặc các bảng nối nhiều-nhiều vốn tồn tại chủ yếu để hỗ trợ bản ghi cha. Ví dụ:

  • Xóa một người dùng nên xóa lịch sử đăng nhập của họ
  • Xóa một đơn hàng nên xóa các mặt hàng trong đơn
  • Xóa một sản phẩm nên xóa các bản ghi trong bảng ánh xạ sản phẩm–danh mục

Đơn giản hóa quản lý vòng đời dữ liệu

Bạn cũng có thể dùng CASCADE để chuyển các quy tắc vòng đời dữ liệu vào trong cơ sở dữ liệu. Thay vì dựa vào mã ứng dụng để tìm các bản ghi liên quan, xóa theo đúng thứ tự và xử lý các trường hợp biên và lỗi, cơ sở dữ liệu sẽ thực thi các quy tắc này một cách nhất quán và nguyên tử.

Bằng cách này, CASCADE đảm bảo rằng dù thao tác xóa được kích hoạt qua ứng dụng, script hay truy vấn quản trị, kết quả luôn nhất quán.

Rủi ro và cạm bẫy của ON DELETE CASCADE

Mặc dù ràng buộc ON DELETE CASCADE tiện lợi, nó có thể rủi ro nếu dùng không đúng cách. Hiểu các cạm bẫy phổ biến rất quan trọng khi thiết kế ràng buộc CASCADE hiệu quả.

Xóa hàng loạt ngoài ý muốn

Rủi ro thường gặp nhất với CASCADE là xóa trên diện rộng không mong muốn. Một câu lệnh DELETE trên bảng cha có thể âm thầm xóa hàng trăm hoặc hàng nghìn hàng liên quan trên nhiều bảng. Điều này có thể dẫn đến mất dữ liệu bất ngờ và khó khôi phục nếu bạn không hiểu rõ mối quan hệ giữa các bảng. 

Thực hành tốt là luôn đảm bảo bạn có thể lần theo quan hệ giữa các khóa ngoại ở bảng cha và bảng con. Nếu mô hình đúng, bạn sẽ biết những bảng nào bị ảnh hưởng bởi một thao tác xóa duy nhất.

Phụ thuộc ẩn trong lược đồ phức tạp

Khi cơ sở dữ liệu phát triển, các bảng tích lũy thêm khóa ngoại, và tài liệu có thể không còn đồng bộ với thực tế. Thách thức nảy sinh khi CASCADE được áp dụng trong các môi trường như vậy, và việc xóa có thể lan qua những chuỗi phụ thuộc lồng sâu mà nhà phát triển hoặc quản trị viên không hay biết.

Từ kinh nghiệm của tôi, tôi khuyên bạn nên kết hợp CASCADE với tài liệu lược đồ rõ ràng và thường xuyên rà soát các quan hệ khóa ngoại.

Hãy thử lộ trình kỹ năng SQL Server for Database Administrators nếu bạn thường xuyên thiết kế hoặc vận hành cơ sở dữ liệu trong công việc. 

Ghi chú và hành vi theo từng hệ quản trị CSDL

Mặc dù khái niệm ON DELETE CASCADE là tiêu chuẩn trong các CSDL quan hệ, mỗi bộ máy có cách thực thi bên dưới hơi khác nhau.

Hành vi của PostgreSQL, MySQL và SQL Server

PostgreSQL, MySQL và SQL Server đều hỗ trợ ON DELETE CASCADE và triển khai tương tự, với vài ngoại lệ sau:

  • MySQL: CASCADE hoạt động tốt với InnoDB, nhưng tránh dây chuyền vòng tròn

  • PostgreSQL: Linh hoạt và cho phép dây chuyền xóa rộng rãi nhất

  • SQL Server: An toàn hơn nhưng hạn chế hơn do các quy tắc đường dẫn dây chuyền đa cấp

Phạm vi giao dịch và tính an toàn khi hoàn tác

Các thao tác xóa dây chuyền được thực thi trong cùng một giao dịch với câu lệnh xóa gốc. Nếu cơ sở dữ liệu gặp lỗi khi cố xóa một hàng con, toàn bộ thao tác sẽ thất bại. Hàng cha không bị xóa và các hàng con đã xóa sẽ được khôi phục.

Hành vi giao dịch này cung cấp một lưới an toàn quan trọng. Nó cho phép bạn thử nghiệm, rà soát hoặc hoàn tác các xóa dây chuyền trước khi cam kết.

Chọn chiến lược ON DELETE phù hợp

Đến đây, bạn đã biết việc chọn chiến lược xóa đúng phụ thuộc vào cách dữ liệu liên quan và cách bạn muốn nó ứng xử theo thời gian. Hãy cân nhắc các hướng dẫn sau để đưa ra lựa chọn DELETE phù hợp cho lược đồ của bạn.

Khi nào CASCADE là lựa chọn đúng

Bạn nên dùng ràng buộc ON DELETE CASCADE khi dữ liệu con hoàn toàn phụ thuộc vào dữ liệu cha về mặt ý nghĩa hoặc sự tồn tại. Ví dụ, bạn có thể dùng trong các trường hợp sau:

  • Các bảng nối trong quan hệ nhiều-nhiều
  • Dữ liệu tạm/thứ cấp, như log hoặc bản ghi lịch sử

Trong các trường hợp trên, dọn dẹp tự động đảm bảo tính nhất quán đồng thời giảm logic xóa thủ công ở lớp ứng dụng.

Tôi khuyên bạn học khóa Joining Data in SQL để tìm hiểu các loại phép nối trong SQL và cách làm việc với các bảng liên quan trong cơ sở dữ liệu.

Khi nào nên tránh CASCADE

Tuy nhiên, bạn nên tránh ràng buộc ON DELETE CASCADE trong lược đồ nếu dữ liệu con có giá trị độc lập hoặc bắt buộc phải được lưu giữ vì lý do pháp lý, kiểm toán hoặc phân tích. Ví dụ, bạn có thể không dùng CASCADE trong:

  • Hồ sơ tài chính và hóa đơn
  • Nhật ký kiểm toán và dữ liệu tuân thủ, như dữ liệu y tế.

Với các trường hợp như vậy, tôi khuyên dùng các quy tắc hạn chế như RESTRICT, SET NULL, hoặc xóa do ứng dụng quản lý để có quyền kiểm soát và khả năng quan sát tốt hơn.

Kết luận

Ràng buộc SQL ON DELETE CASCADE là một công cụ tự động hóa mạnh mẽ giúp duy trì toàn vẹn tham chiếu bằng cách tự động loại bỏ dữ liệu phụ thuộc khi một hàng cha bị xóa. Khi dùng đúng cách, nó đơn giản hóa việc dọn dẹp, giảm logic xóa thủ công và đảm bảo hành vi nhất quán trên các ứng dụng và script. Để tránh xóa ngoài ý muốn, luôn thận trọng khi dùng CASCADE nếu bạn chưa hiểu đầy đủ các quan hệ trong lược đồ cơ sở dữ liệu.

Tôi khuyên bạn học khóa Database Design, nơi bạn sẽ học cách tạo và quản lý cơ sở dữ liệu cũng như chọn DBMS phù hợp với nhu cầu. Tôi cũng khuyên thử lộ trình nghề nghiệp Associate Data Engineer in SQL để học các nền tảng về kỹ thuật dữ liệu và kho dữ liệu.  

Allan Ouko

Tác giả

Allan Ouko

Biên tập viên kỹ thuật về Khoa học dữ liệu với kinh nghiệm thực tế trong phân tích dữ liệu, trí tuệ doanh nghiệp và khoa học dữ liệu. Tôi viết nội dung thực tiễn, tập trung vào ngành về SQL, Python, Power BI, Databricks và kỹ thuật dữ liệu, dựa trên công việc phân tích trong thế giới thực. Bài viết của tôi kết nối chiều sâu kỹ thuật với tác động kinh doanh, giúp các chuyên gia chuyển đổi dữ liệu thành những quyết định vững chắc.

Câu hỏi thường gặp về SQL ON DELETE CASCADE

ON DELETE CASCADE xóa hàng con trước hay hàng cha trước?

ON DELETE CASCADE xóa các hàng con trước để bảo toàn toàn vẹn tham chiếu.

ON DELETE CASCADE khác gì so với RESTRICT?

CASCADE tự động xóa các hàng phụ thuộc, trong khi RESTRICT chặn thao tác xóa nếu còn hàng con tồn tại.

ON DELETE CASCADE khác gì so với SET NULL?

CASCADE xóa các hàng con; SET NULL giữ lại chúng nhưng xóa tham chiếu khóa ngoại.

Có thể hoàn tác ON DELETE CASCADE không?

Có, xóa dây chuyền diễn ra trong một giao dịch và bạn có thể hoàn tác trước khi commit.

ON DELETE CASCADE có phải là hành vi mặc định trong SQL không?

Không, bạn phải định nghĩa rõ ON DELETE CASCADE trong ràng buộc khóa ngoại khi tạo bảng hoặc trên bảng hiện có.

Chủ đề