ShareYourGroupShareYourGroupSQL

Lesson 22 of 26 · see the practice database

Changing tables, dropping them, and indexes

Tables change over time. The business wants to record something new, a column was badly named, an old table is no longer needed. ALTER TABLE changes the structure of a table without touching the rest of its data. DROP TABLE removes a table. This lesson covers both, and then indexes, the main tool for making queries fast.

Adding a column

ALTER TABLE customers ADD COLUMN phone TEXT;

Result

Done.

SELECT id, name, phone FROM customers LIMIT 3;

Result

idnamephone
1Asha VermaNULL
2Ravi KumarNULL
3Meena GillNULL

3 rows

The new column exists in every row, and it is empty: all the existing rows hold NULL in it. Fill it with UPDATE.

UPDATE customers SET phone = '98765 00001' WHERE id = 1;

Result

Done. 1 row changed.

Give a default, and existing rows get that value instead of NULL.

ALTER TABLE products ADD COLUMN active INTEGER NOT NULL DEFAULT 1;

Result

Done.

SELECT id, name, active FROM products LIMIT 3;

Result

idnameactive
1Basmati Rice 5 kg1
2Toor Dal 1 kg1
3Sunflower Oil 1 L1

3 rows

A new column that is NOT NULL needs a default. Otherwise the database would not know what to put in the rows that already exist.

Renaming

ALTER TABLE customers RENAME COLUMN phone TO mobile;

Result

Done.

ALTER TABLE employees RENAME TO staff;

Result

Done.

SELECT name, department FROM staff LIMIT 2;

Result

namedepartment
Anita KapoorManagement
Rohit BansalSales

2 rows

Renaming is quick for the database and can be slow for people: every saved query, report and program that used the old name stops working. On a shared database, agree a rename with everyone who uses the table first. We rename the table back so that later examples work.

ALTER TABLE staff RENAME TO employees;

Result

Done.

Removing a column

ALTER TABLE customers DROP COLUMN mobile;

Result

Done.

The column and everything in it are gone for good. Check first that nothing still uses it.

What ALTER TABLE can do differs by database

This is one of the least uniform parts of SQL.

ChangeSQLiteMySQLPostgreSQLSQL Server
Add a columnADD COLUMNADD COLUMNADD COLUMNADD
Rename a columnRENAME COLUMN a TO bRENAME COLUMN a TO bRENAME COLUMN a TO bsp_rename procedure
Change a column's typenot supportedMODIFY COLUMNALTER COLUMN ... TYPEALTER COLUMN
Drop a columnDROP COLUMNDROP COLUMNDROP COLUMNDROP COLUMN

SQLite cannot change the type of a column or add most constraints to an existing table. The usual way round is to create a new table with the right design, copy the data across with INSERT ... SELECT, drop the old table and rename the new one.

DROP TABLE

DROP TABLE deletes a table: its structure, its data, everything.

CREATE TABLE scratch (note TEXT);

Result

Done.

DROP TABLE scratch;

Result

Done.

SELECT * FROM scratch;

What the database says

Error: no such table: scratch

There is no confirmation and, outside a transaction, no undo. Dropping a table that does not exist is an error; DROP TABLE IF EXISTS name avoids that in scripts.

DELETE, TRUNCATE or DROP?

StatementRemovesTable still exists?
DELETE FROM t WHERE ...the rows that matchyes
DELETE FROM tall rowsyes, empty
TRUNCATE TABLE tall rows, quicklyyes, empty
DROP TABLE trows and the table itselfno

Interviewers like this question. DELETE is a data statement and can be filtered. TRUNCATE and DROP are structure statements and cannot.

Indexes: why some searches are fast

Think of the index at the back of a textbook. To find every page that mentions "photosynthesis", you do not read the whole book. You look the word up in the index, which is in alphabetical order, and go straight to the pages.

A database index works the same way. Without one, a search such as WHERE city = 'Delhi' makes the database read every row of the table. That is called a full table scan. With an index on city, it can jump to the matching rows. On twelve rows nobody can tell the difference. On twelve million, it is the difference between a blink and a long wait.

Creating an index

CREATE INDEX idx_customers_city ON customers (city);

Result

Done.

Give the index a name, the table, and the column. Nothing looks different afterwards. Queries are written exactly as before and return exactly the same rows. The database simply uses the index when it helps.

SELECT name, city FROM customers WHERE city = 'Delhi';

Result

namecity
Ravi KumarDelhi
Imran AliDelhi

2 rows

An index can cover two columns. The order matters: an index on (status, order_date) helps searches on status alone, or on status and date together, but not on date alone, in the same way that a phone book sorted by surname and then first name is no help in finding everyone called Ravi.

CREATE INDEX idx_orders_status_date ON orders (status, order_date);

Result

Done.

A unique index also enforces that no two rows share a value.

CREATE UNIQUE INDEX idx_products_name ON products (name);

Result

Done.

What to index

What indexes cost

Indexes are not free, which is why you do not index everything.

The sensible approach is to add indexes for the queries you really run, and to measure.

Asking the database what it will do

Every database can explain how it plans to run a query. In SQLite, put EXPLAIN QUERY PLAN in front.

EXPLAIN QUERY PLAN
SELECT name FROM customers WHERE city = 'Delhi';

Result

idparentnotuseddetail
3062SEARCH customers USING INDEX idx_customers_city (city=?)

1 row

The answer mentions the index made above, which shows it is being used. MySQL and PostgreSQL use the word EXPLAIN alone. Reading plans is a skill of its own. For now it is enough to know that the tool exists and that the word "scan" on a big table is the thing to look for.

Removing an index

DROP INDEX idx_products_name;

Result

Done.

Dropping an index loses no data. Only the speed-up goes. MySQL and SQL Server need the table name too: DROP INDEX idx_products_name ON products.

Try it yourself

In the practice box, press Reset the database first.

Exercise 1. Add a text column called notes to the orders table.

Open in the practice box

Show one answer
ALTER TABLE orders ADD COLUMN notes TEXT;

Done.

Exercise 2. Create an index called idx_products_category on the category column of products.

Open in the practice box

Show one answer
CREATE INDEX idx_products_category ON products (category);

Done.

Exercise 3. Create a table called temp_list with one text column item, and then drop it. Two statements.

Open in the practice box

Show one answer
CREATE TABLE temp_list (item TEXT);
DROP TABLE temp_list;

Done.

Examples on this page were run with SQLite 3.50.4 on 12 November 2026. The results shown are the real results.

This is an independent learning site. It is not connected with the makers of any database product. MySQL, PostgreSQL, SQL Server, Oracle and SQLite are named only so that you know where a piece of SQL works. The shop, its customers and its staff in the practice database are made up.