Use MySQL ALTER TABLE to change the structure of an existing table. You can add, modify, rename, or drop columns; change defaults; add or remove indexes; rename the table; and change other table properties.
ALTER TABLE student
ADD COLUMN rank INT NULL;
ALTER TABLE table_name
alter_action;
The action can add, modify, rename, or drop a column or constraint. MySQL also allows several alter actions in one statement.
Add a nullable integer column:
ALTER TABLE student
ADD COLUMN rank INT NULL;
Add a required column with a default:
ALTER TABLE student
ADD COLUMN rank INT NOT NULL DEFAULT 10;
INT(3) or INT(5) do not limit an integer to three or five digits. Choose the integer datatype according to the numeric range you need.When existing rows already exist, think about what value the new column should contain for those rows. A meaningful DEFAULT, a nullable transition, or a staged migration may be safer than adding a required column without planning the existing data.
MySQL can place a new column at the beginning of the table definition or after another column.
ALTER TABLE student
ADD COLUMN last_name VARCHAR(50) NULL
AFTER name;
To place a column first:
ALTER TABLE student
ADD COLUMN student_code VARCHAR(20) NOT NULL FIRST;
Use MODIFY COLUMN when the column name stays the same but its datatype, NULL rule, default, or other definition changes.
ALTER TABLE student
MODIFY COLUMN last_name VARCHAR(80) NULL;
For example, change mark to an unsigned small integer:
ALTER TABLE student
MODIFY COLUMN mark TINYINT UNSIGNED NOT NULL DEFAULT 0;
On MySQL 8.0+, use RENAME COLUMN when only the name changes:
ALTER TABLE student
RENAME COLUMN mark TO student_mark;
This is clearer than repeating the full datatype definition when only the column name needs to change.
CHANGE COLUMN can rename a column and redefine it in the same operation. This syntax is also useful on older MySQL versions that do not support RENAME COLUMN.
ALTER TABLE student
CHANGE COLUMN mark student_mark
TINYINT UNSIGNED NOT NULL DEFAULT 0;
CHANGE COLUMN, you must provide the new complete column definition. If you forget an existing attribute that should remain, the resulting column may not match the old definition.Set a default value:
ALTER TABLE student
ALTER COLUMN mark
SET DEFAULT 0;
Remove the default:
ALTER TABLE student
ALTER COLUMN mark
DROP DEFAULT;
This changes the default for future INSERT operations; it does not rewrite existing row values.
ALTER TABLE student
DROP COLUMN last_name;
Add uniqueness to an existing column:
ALTER TABLE message_table
ADD UNIQUE (msg_id);
This succeeds only if the existing data already satisfies the new uniqueness rule.
To remove that unique index, first identify its index name with SHOW INDEX and then drop it:
SHOW INDEX FROM message_table;
ALTER TABLE message_table
DROP INDEX index_name;
See PRIMARY KEY constraints for the difference between a primary key and other unique keys.
A primary key uniquely identifies each row and cannot contain NULL. A table has one PRIMARY KEY, which may consist of one or more columns.
Primary Key constraintAn AUTO_INCREMENT column must be indexed, and a table can have only one AUTO_INCREMENT column.
If msg_id already contains unique, non-NULL integer values, you can make it the primary key and add AUTO_INCREMENT:
ALTER TABLE message_table
ADD PRIMARY KEY (msg_id);
ALTER TABLE message_table
MODIFY COLUMN msg_id
INT UNSIGNED NOT NULL AUTO_INCREMENT;
If the table already has a primary key and msg_id should remain a secondary key, a UNIQUE index can satisfy the indexing requirement instead:
ALTER TABLE message_table
ADD UNIQUE (msg_id);
ALTER TABLE message_table
MODIFY COLUMN msg_id
INT UNSIGNED NOT NULL AUTO_INCREMENT;
See MySQL AUTO_INCREMENT.
ALTER TABLE student
RENAME TO students;
Renaming a table can break application code, views, routines, documentation, or integrations that still use the old name. Check dependencies before changing it.
MySQL allows multiple alter actions in one statement:
ALTER TABLE student
ADD COLUMN last_name VARCHAR(80) NULL,
MODIFY COLUMN class VARCHAR(20) NOT NULL,
ADD INDEX idx_class (class);
Combining compatible changes can reduce repeated table-alter operations, but the statement becomes more consequential. Test it carefully before production use.
ALTER TABLE must respect the data already stored in the table.
This fails if duplicate values are already present:
ALTER TABLE student
ADD UNIQUE (name);
Check duplicates first:
SELECT name,
COUNT(*) AS row_count
FROM student
GROUP BY name
HAVING COUNT(*) > 1;
Check whether NULL values already exist before making the column required:
SELECT COUNT(*) AS null_rows
FROM student
WHERE last_name IS NULL;
Resolve incompatible existing rows before applying the stricter definition.
Before altering a table, inspect its current definition.
DESCRIBE student;
or:
SHOW CREATE TABLE student;
SHOW CREATE TABLE is especially useful because it exposes the full stored CREATE definition, including indexes and table options.
| Field | Type | Null | Key / Extra |
|---|---|---|---|
| id | int unsigned | No | PRIMARY KEY, auto_increment |
| name | varchar(50) | No | |
| class | varchar(20) | No | |
| mark | tinyint unsigned | No | default 0 |
Schema-changing statements such as many forms of ALTER TABLE are DDL operations. In MySQL, DDL commonly causes implicit commits and should not be treated like ordinary transactional INSERT/UPDATE/DELETE work.
Integer display width is not a value-length constraint. Use the correct integer type and application validation.
NOT NULL only disallows NULL. If zero should be the default, declare DEFAULT 0 explicitly when that meaning is correct.
Use MODIFY when the name remains the same. Use RENAME COLUMN when only the name changes on MySQL 8.0+, and CHANGE when you need rename + definition change or older-version compatibility.
Restate the intended complete column definition so existing attributes are not accidentally lost.
The ALTER fails if current rows violate the proposed uniqueness constraint.
Application code, indexes, generated columns, views, or reports may depend on the column.
Cost depends on the specific change, table size, MySQL version, storage engine, and algorithm chosen by MySQL.
ALTER TABLE changes an existing table definition, including columns, indexes, constraints, defaults, and the table name.
MODIFY changes a column definition without renaming it. CHANGE can rename the column and redefine it in one operation.
Use ALTER TABLE table_name RENAME COLUMN old_name TO new_name when only the name is changing.
No. NOT NULL only prevents NULL. Use DEFAULT 0 explicitly if zero is the correct default value.
Yes, if the column is an appropriate integer type, is indexed, contains compatible unique values, and the table does not already have another AUTO_INCREMENT column.
Yes. Dropping a column removes the data stored in that column, and incompatible datatype changes can also cause conversion problems. Back up important data first.
Do not rely on ordinary transaction rollback for MySQL DDL. ALTER TABLE operations commonly involve implicit commits and should be planned as schema migrations.
Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.
| tamil | 10-02-2009 |
| This site looks good | |
| nandy | 25-02-2010 |
| Very useful and reference-friendly. | |
| Dave | 26-09-2010 |
| I noticed that the code to make a field unique and auto_increment is PHP code, not a direct SQL command, while the code for changing the name of a field is straight SQL code. I am inexperienced in PHP however I can use SQL commands fine. Please tell me the equivalent SQL code for making a field unique and auto_increment. Removing the quotes, parens and variable names does not seem to work. | |
| smo | 26-09-2010 |
| These are SQL commands only. There is no PHP code here. Tested in phpmyadmin with MySQL | |
| bhavik | 19-03-2011 |
| i have 1 question. first we create table and define two column id and name. but that time we missed to define id as auto_increment, now what we do. i want solved this problem with query. can we do that with ATLER TABLE ? please give me the answer sir... | |