00:00

MySQL Drop Table

Last updated: 4 min read

When a table is no longer needed, DROP TABLE removes it completely: its structure, all its rows, its indexes and its triggers. Like dropping a database, it is permanent, so this tutorial covers the safe way to do it and the errors you may run into.

1. Syntax

syntax.sql
DROP [TEMPORARY] TABLE [IF EXISTS] table1 [, table2, ...] [RESTRICT | CASCADE];
  • TEMPORARY: drop only a temporary table, never a permanent one with the same name.
  • IF EXISTS: give a note instead of an error if a table is missing.
  • Several tables can be dropped in one statement.
  • RESTRICT and CASCADE are accepted but do nothing in MySQL.
DELETE, TRUNCATE and DROP comparedDELETE removes chosen rows and keeps the table. TRUNCATE removes all rows quickly and keeps the empty table. DROP removes the table structure and all rows.DELETE FROM t WHERE …idname1A2B3Csome rows gonetable staysTRUNCATE TABLE tidname1A2B3Call rows goneempty table staysDROP TABLE tidname1A2B3Crows + structure gonetable no longer exists
Figure 1: DROP TABLE removes the whole table, structure included.

2. Dropping a Table

query.sql
SHOW TABLES;

Before

Tables_in_blogdb
authors
old_stats
post_list
posts
tags
temp_import
query.sql
DROP TABLE old_stats;
Output
Query OK, 0 rows affected
query.sql
SHOW TABLES;

After

Tables_in_blogdb
authors
post_list
posts
tags
temp_import

3. Dropping Several Tables at Once

drop-many.sql
DROP TABLE tags, temp_import;
SHOW TABLES;

Result: 3 rows

Tables_in_blogdb
authors
post_list
posts

4. IF EXISTS

query.sql
DROP TABLE old_stats;
Output
ERROR 1051 (42S02): Unknown table 'blogdb.old_stats'
query.sql
DROP TABLE IF EXISTS old_stats;
SHOW WARNINGS;
Output
Query OK, 0 rows affected, 1 warning

Result: 1 row

LevelCodeMessage
Note1051Unknown table 'blogdb.old_stats'
Database migration and test scripts usually start with DROP TABLE IF EXISTS so they can run again and again.

5. Tables Referenced by Foreign Keys

You can't drop a table that another table's foreign key points to. posts.author_id references authors:

query.sql
DROP TABLE authors;
Output
ERROR 3730 (HY000): Cannot drop table 'authors' referenced by a foreign key constraint 'posts_ibfk_1' on table 'posts'.

Find the referencing tables in information_schema:

query.sql
SELECT table_name, column_name, referenced_table_name, constraint_name
FROM information_schema.key_column_usage
WHERE referenced_table_schema = 'blogdb' AND referenced_table_name = 'authors';

Result: 1 row

TABLE_NAMECOLUMN_NAMEREFERENCED_TABLE_NAMECONSTRAINT_NAME
postsauthor_idauthorsposts_ibfk_1

There are three ways forward:

  1. Drop the child table first (here posts), or both together in child-then-parent order: DROP TABLE posts, authors;
  2. Remove the foreign key: ALTER TABLE posts DROP FOREIGN KEY posts_ibfk_1;
  3. Temporarily disable checks (SET foreign_key_checks = 0;), only for controlled maintenance, because it can leave child rows pointing nowhere.
drop-in-order.sql
DROP TABLE posts, authors;
SHOW TABLES;

Result: 1 row

Tables_in_blogdb
post_list

6. What Happens to Views

Views that use a dropped table are not removed; they become invalid:

query.sql
SELECT * FROM post_list;
Output
ERROR 1356 (HY000): View 'blogdb.post_list' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them

Drop or recreate such views. CHECK TABLE post_list; also reports broken views.

query.sql
DROP VIEW post_list;
Output
Query OK, 0 rows affected

7. Dropping Temporary Tables

A temporary table can hide a permanent table of the same name. DROP TEMPORARY TABLE guarantees you only remove the temporary one:

temporary.sql
CREATE TABLE report (id INT);
INSERT INTO report VALUES (1), (2), (3);
CREATE TEMPORARY TABLE report (id INT);       -- hides the real table in this session
SELECT COUNT(*) AS visible_rows FROM report;   -- the temporary one is empty

DROP TEMPORARY TABLE report;
SELECT COUNT(*) AS visible_rows FROM report;   -- the real table is back

While the temporary table exists

visible_rows
0

After DROP TEMPORARY TABLE

visible_rows
3

8. Safety Checklist

  1. Check you are on the right server and database: SELECT @@hostname, DATABASE();
  2. Count the rows: SELECT COUNT(*) FROM table_name;
  3. Back up the table: mysqldump -u root -p dbname table_name > table_name.sql, or keep a copy with CREATE TABLE t_backup AS SELECT * FROM t;
  4. Check for foreign keys, views and application code that use it.
  5. Remember: DDL commits immediately, so ROLLBACK can't bring the table back.

9. DROP vs TRUNCATE vs DELETE

DELETETRUNCATEDROP
RemovesChosen rows (or all)All rowsRows + table structure
WHERE allowedYesNoNo
Rollback possibleYes (in a transaction)NoNo
Speed on big tablesSlow (row by row, logged)Fast (recreates table)Fast
Resets AUTO_INCREMENTNoYesTable is gone
Fires DELETE triggersYesNoNo (triggers are dropped)
Statement typeDMLDDLDDL

10. Summary

  • DROP TABLE t; removes a table's structure and data permanently.
  • Use IF EXISTS in scripts and list several tables to drop them together.
  • Drop child tables before parents, or remove the foreign key first.
  • Views on a dropped table become invalid; use DROP TEMPORARY TABLE for temporary tables.
  • Back up first: there is no undo.