Skip to content

MySQL - On Delete Cascade

The ON DELETE CASCADE constraint is a feature of foreign keys in relational databases like MySQL. It establishes a rule that automatically maintains data consistency, or referential integrity, between a parent table and a child table.

When you define a foreign key with ON DELETE CASCADE, deleting a record from the parent table will automatically trigger the deletion of all corresponding records in the child table. Without this constraint, the database server would, by default (ON DELETE RESTRICT), prevent you from deleting a parent record if it’s referenced by any child records, forcing you to manually delete the child records first.

Let’s model a simple system for users and their blog posts. A user can have multiple posts, creating a one-to-many relationship. If a user is deleted, we want all their posts to be deleted as well.

First, we create the users table. It’s best practice to use the InnoDB storage engine, which is the default in modern MySQL and supports foreign key constraints.

CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB;

Now, let’s insert some sample users:

INSERT INTO users (username, email) VALUES
('alice', 'alice@example.com'),
('bob', 'bob@example.com'),
('charlie', 'charlie@example.com');

The users table now contains:

user_idusernameemailcreated_at
1alicealice@example.com…
2bobbob@example.com…
3charliecharlie@example.com…

Step 2: Create the Child Table with ON DELETE CASCADE

Section titled “Step 2: Create the Child Table with ON DELETE CASCADE”

Next, we create the posts table. The author_id column will be a foreign key that references user_id in the users table. Here, we specify ON DELETE CASCADE.

CREATE TABLE posts (
post_id INT AUTO_INCREMENT PRIMARY KEY,
author_id INT NOT NULL,
title VARCHAR(255) NOT NULL,
content TEXT,
published_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (author_id) REFERENCES users(user_id) ON DELETE CASCADE
) ENGINE=InnoDB;

Let’s add some posts for our users:

INSERT INTO posts (author_id, title, content) VALUES
(1, 'My First Post', 'Hello world!'),
(2, 'Databases are Fun', 'A post about SQL.'),
(2, 'Advanced SQL', 'Exploring window functions.'),
(3, 'Web Development Trends', 'A look at modern frameworks.');

The posts table now looks like this:

post_idauthor_idtitlecontentpublished_at
11My First PostHello world!…
22Databases are FunA post about SQL.…
32Advanced SQLExploring window functions.…
43Web Development TrendsA look at modern frameworks.…

Step 3: Deleting a Record from the Parent Table

Section titled “Step 3: Deleting a Record from the Parent Table”

Now, let’s see the ON DELETE CASCADE constraint in action. We will delete the user ‘bob’, who has user_id = 2. Bob has authored two posts.

DELETE FROM users WHERE user_id = 2;

The query executes successfully. Let’s verify the contents of both tables.

Querying the users table:

SELECT * FROM users;

As expected, the user with user_id = 2 is gone:

user_idusernameemailcreated_at
1alicealice@example.com…
3charliecharlie@example.com…

Querying the posts table:

SELECT * FROM posts;

The cascaded delete worked perfectly. Both posts authored by ‘bob’ (with author_id = 2) were automatically removed from the posts table, maintaining referential integrity.

post_idauthor_idtitlecontentpublished_at
11My First PostHello world!…
43Web Development TrendsA look at modern frameworks.…
  • Use with Caution: ON DELETE CASCADE is powerful but can lead to unintentional mass data loss if used incorrectly. Ensure it’s only applied to relationships where the child entity cannot exist without the parent (e.g., posts cannot exist without a user).
  • Alternatives: For other scenarios, consider ON DELETE SET NULL (sets the foreign key in the child table to NULL) or ON DELETE RESTRICT (the default, which prevents deletion). The choice depends entirely on your business logic.
  • Performance: Cascading deletes on very large tables can be resource-intensive and may lock tables for a significant duration. Always test performance in a staging environment.
  • Engine Support: This feature is primarily supported by the InnoDB storage engine, which is the standard choice for modern applications requiring relational integrity and transactions.