MySQL Rename Table
Table names chosen early in a project don't always age well: emp might need to become employees. MySQL renames tables instantly with RENAME TABLE or ALTER TABLE … RENAME, because only metadata changes and no rows are copied. This tutorial covers both statements, atomic swaps, moving tables between databases, and the side effects to watch for.
1. Syntax
RENAME TABLE old_name TO new_name [, old_name2 TO new_name2 ...];
ALTER TABLE old_name RENAME [TO | AS] new_name;
| RENAME TABLE | ALTER TABLE … RENAME | |
|---|---|---|
| Several tables in one statement | Yes, atomically | No, one table |
| Combine with other changes | No | Yes, e.g. add a column in the same statement |
| Works on temporary tables | Yes (8.0.13+) | Yes |
| Privileges needed | ALTER and DROP on old, CREATE and INSERT on new | Same |
2. Renaming a Table
RENAME TABLE emp TO employees;
SHOW TABLES;
Result: 3 rows
| Tables_in_hrms |
|---|
| dept |
| employees |
| sales_team |
The same with ALTER TABLE:
ALTER TABLE dept RENAME TO departments;
SHOW TABLES;
Result: 3 rows
| Tables_in_hrms |
|---|
| departments |
| employees |
| sales_team |
3. What Moves with the Table and What Doesn't
| Item | After rename |
|---|---|
| Rows, columns, indexes | Unchanged |
| Foreign keys on the table and pointing to it | Updated automatically |
| Triggers | Stay attached to the table |
| Views that use the old name | Broken: they still mention the old name |
| Stored procedures, functions, events | Not updated: SQL inside them still uses the old name |
| Table-level privileges (GRANT … ON db.old) | Not moved: grant again on the new name |
The foreign key now references departments:
SELECT constraint_name, table_name, referenced_table_name
FROM information_schema.referential_constraints
WHERE constraint_schema = 'hrms';
Result: 1 row
| CONSTRAINT_NAME | TABLE_NAME | REFERENCED_TABLE_NAME |
|---|---|---|
| fk_emp_dept | employees | departments |
But the view is broken because it still says emp:
SELECT * FROM sales_team;
ERROR 1356 (HY000): View 'hrms.sales_team' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
Recreate it with the new name:
CREATE OR REPLACE VIEW sales_team AS SELECT name FROM employees WHERE dept_id = 1;
SELECT * FROM sales_team;
Result: 2 rows
| name |
|---|
| Arun |
| Chandu |
And the table-level grant still names the old table:
SHOW GRANTS FOR 'hr_app'@'localhost';
Result: 2 rows
| Grants for hr_app@localhost |
|---|
| GRANT USAGE ON *.* TO `hr_app`@`localhost` |
| GRANT SELECT ON `hrms`.`emp` TO `hr_app`@`localhost` |
REVOKE SELECT ON hrms.emp FROM 'hr_app'@'localhost';
GRANT SELECT ON hrms.employees TO 'hr_app'@'localhost';
SHOW GRANTS FOR 'hr_app'@'localhost';
Result: 2 rows
| Grants for hr_app@localhost |
|---|
| GRANT USAGE ON *.* TO `hr_app`@`localhost` |
| GRANT SELECT ON `hrms`.`employees` TO `hr_app`@`localhost` |
4. Renaming Several Tables at Once
All renames in one RENAME TABLE happen together; if one fails, none happen:
RENAME TABLE employees TO staff, departments TO teams;
SHOW TABLES;
Result: 3 rows
| Tables_in_hrms |
|---|
| sales_team |
| staff |
| teams |
RENAME TABLE staff TO employees, teams TO staff;
SHOW TABLES;
Result: 3 rows
| Tables_in_hrms |
|---|
| employees |
| sales_team |
| staff |
Renames run left to right, so teams TO staff works: by then the old staff has already become employees. If any step fails, the whole statement fails and nothing changes. Here the last step refers to employees, which the first step already renamed:
RENAME TABLE employees TO people, staff TO employees_typo, employees TO x;
ERROR 1146 (42S02): Table 'hrms.employees' doesn't exist
SHOW TABLES;
Nothing was renamed
| Tables_in_hrms |
|---|
| employees |
| sales_team |
| staff |
5. Swapping a Table with a New Version
CREATE TABLE prices (sku VARCHAR(10) PRIMARY KEY, price DECIMAL(8,2));
INSERT INTO prices VALUES ('A1', 100), ('B2', 250);
-- load the new price list into a separate table
CREATE TABLE prices_new LIKE prices;
INSERT INTO prices_new VALUES ('A1', 110), ('B2', 240), ('C3', 99);
-- swap in one atomic step
RENAME TABLE prices TO prices_old, prices_new TO prices;
SELECT * FROM prices;
Result: 3 rows
| sku | price |
|---|---|
| A1 | 110.00 |
| B2 | 240.00 |
| C3 | 99.00 |
6. Moving a Table to Another Database
Qualify the new name with a database to move the table there (same server only):
CREATE DATABASE archive;
RENAME TABLE hrms.prices_old TO archive.prices_2025;
SHOW TABLES FROM archive;
Result: 1 row
| Tables_in_archive |
|---|
| prices_2025 |
7. Common Errors
RENAME TABLE employees TO staff;
ERROR 1050 (42S01): Table 'staff' already exists
RENAME TABLE missing_table TO something;
ERROR 1146 (42S02): Table 'hrms.missing_table' doesn't exist
| Error | Cause |
|---|---|
| 1050: Table '…' already exists | The new name is taken |
| 1146: Table '…' doesn't exist | Typo in the old name or wrong database |
| Statement waits | Another session has an open transaction on the table (metadata lock) |
8. Practice Exercises
Exercise 1: Rename employees to team_members using ALTER TABLE and confirm.
ALTER TABLE employees RENAME TO team_members;
SHOW TABLES LIKE 'team%';
Result: 1 row
| Tables_in_hrms (team%) |
|---|
| team_members |
Exercise 2: Swap the names of staff and team_members in one statement.
RENAME TABLE staff TO tmp_swap, team_members TO staff, tmp_swap TO team_members;
SHOW TABLES;
Result: 4 rows
| Tables_in_hrms |
|---|
| prices |
| sales_team |
| staff |
| team_members |
9. Summary
RENAME TABLE a TO b;orALTER TABLE a RENAME TO b;renames instantly.RENAME TABLEcan rename many tables atomically, which is ideal for swaps.- Foreign keys and triggers follow the table; views, routines and table-level grants do not.
RENAME TABLE db1.t TO db2.tmoves a table between databases on the same server.