Q1When you run ALTER TABLE table ADD COLUMN status TEXT DEFAULT 'active'; on an existing table, what happens to the status column on existing rows?
Adding/Changing Constraints and Table Redefinition
Using a legacy_user table, learn how to retrofit columns with ALTER TABLE ADD COLUMN ... DEFAULT and how to rebuild the table to make email NOT NULL UNIQUE (CREATE new → INSERT SELECT → DROP → RENAME) — all hands-on in the browser.
The data we'll use — legacy_user
Tables in production often turn out to need constraints that weren't included in the original design.
Things like "attach a default value to this column," "make email duplication-free (UNIQUE)," or "mark this required field as NOT NULL."
This article covers adding columns and retrofitting default values, and the table-rebuild procedure for adding constraints to an existing table.
ALTER TABLE ADD COLUMN — retrofit a column and default value
To add a new column to an existing table, use ALTER TABLE table ADD COLUMN col_name type constraint.
Attaching DEFAULT value sets the default value used when the column is omitted, and at ALTER time the value also fills in for every existing row.
ADD COLUMN even accepts NOT NULL when combined with DEFAULT (existing rows are filled with the default, so they don't violate NOT NULL).
On the other hand, ADD COLUMN can't directly attach UNIQUE or a NOT NULL without a default.
Those require a "table rebuild."
-- Add a column with DEFAULT (use a throwaway table to see the behavior)
DROP TABLE IF EXISTS alter_demo;
CREATE TABLE alter_demo(id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO alter_demo VALUES (1,'Alice'),(2,'Bob');
-- Add created_on with a DEFAULT → existing rows get the value too
ALTER TABLE alter_demo ADD COLUMN created_on TEXT DEFAULT '2024-01-01';
-- NOT NULL is also fine when combined with DEFAULT
ALTER TABLE alter_demo ADD COLUMN status TEXT NOT NULL DEFAULT 'active';
SELECT * FROM alter_demo ORDER BY id;
Adding constraints after the fact means rebuilding the table
In MySQL you can attach constraints directly to an existing table, like ALTER TABLE legacy_user ADD CONSTRAINT uq_email UNIQUE (email);.
In this course's console, retrofitting UNIQUE or NOT NULL onto an existing table goes through the table-rebuild procedure: "create a new table with the constraints you want, copy the existing data over, and replace the old table."
MySQL / PostgreSQL also perform this rebuild pattern internally for some operations (like column type changes), depending on the tool.
The procedure follows the figure below: turn off the foreign-key check, then CREATE the new table → copy all rows → DROP the old table → RENAME the new table → restore the check.
About MySQL's ADD CONSTRAINT / AUTO_INCREMENT / column comments
The ALTER TABLE ... ADD CONSTRAINT, AUTO_INCREMENT, and column comment (COMMENT '...') syntax shown below is MySQL syntax.
The browser console in this course can't run them, so these two code blocks are read-only (don't try to execute them).
In this course's console, retrofit constraints via the table rebuild in the section below, and use INTEGER PRIMARY KEY for auto-numbering.
-- MySQL syntax (don't run this in the course's console — just read it)
-- MySQL: attach a UNIQUE constraint directly to an existing table
ALTER TABLE legacy_user ADD CONSTRAINT uq_email UNIQUE (email);
-- MySQL: change to NOT NULL via MODIFY
ALTER TABLE legacy_user MODIFY email VARCHAR(255) NOT NULL;
-- MySQL: auto-numbering is the AUTO_INCREMENT column attribute; descriptions are column comments
CREATE TABLE member (
member_id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) NOT NULL UNIQUE COMMENT 'login email'
);
-- In this course's console, get the AUTO_INCREMENT equivalent via INTEGER PRIMARY KEY
CREATE TABLE member (
member_id INTEGER PRIMARY KEY,
email TEXT NOT NULL UNIQUE
);
-- Skeleton of the table-rebuild (use throwaway table rebuild_demo to see the behavior)
DROP TABLE IF EXISTS rebuild_demo;
CREATE TABLE rebuild_demo(id INTEGER PRIMARY KEY, email TEXT);
INSERT INTO rebuild_demo VALUES (1,'a@example.com'),(2,'b@example.com');
-- ① Disable the foreign-key check
PRAGMA foreign_keys=OFF;
-- ② New table with desired constraints (email NOT NULL UNIQUE)
CREATE TABLE rebuild_demo_new(
id INTEGER PRIMARY KEY,
email TEXT NOT NULL UNIQUE
);
-- ③ Copy existing data over
INSERT INTO rebuild_demo_new(id, email)
SELECT id, email FROM rebuild_demo;
-- ④ Drop the old table, ⑤ rename the new one to the old name
DROP TABLE rebuild_demo;
ALTER TABLE rebuild_demo_new RENAME TO rebuild_demo;
-- ⑥ Restore the foreign-key check
PRAGMA foreign_keys=ON;
-- Confirm the constraints are in place (duplicate email will now error)
SELECT sql FROM sqlite_master WHERE name='rebuild_demo';
Knowledge Check
Answer each question one by one.
Q2Which method does this course's console use to retrofit a UNIQUE constraint onto an existing table?
Q3Why do you run PRAGMA foreign_keys=OFF; at the start of the table rebuild and restore it to ON at the end?