DDL and CRUD Operations
SQL command categories, CREATE and ALTER TABLE, DELETE vs TRUNCATE vs DROP, INSERT, UPDATE, DELETE, SELECT, pagination and the SQL that Spring Data JPA generates.
#Introduction
The previous chapter covered how MySQL works internally. Now we'll start writing SQL like a backend developer.
#SQL Command Categories
Every SQL command belongs to one of these categories:
| Category | Meaning | Commands |
|---|---|---|
| DDL | Data Definition Language | CREATE, ALTER, DROP, TRUNCATE |
| DML | Data Manipulation Language | INSERT, UPDATE, DELETE |
| DQL | Data Query Language | SELECT |
| TCL | Transaction Control Language | COMMIT, ROLLBACK, SAVEPOINT |
| DCL | Data Control Language | GRANT, REVOKE |
Think of it like Java:
| SQL | Java analogy |
|---|---|
| DDL | Designing classes |
| DML | Creating and changing objects |
| DQL | Reading objects |
| TCL | Undo / commit changes |
| DCL | Access control |
#DDL (Data Definition Language)
DDL changes the structure of the database:
CREATE DATABASE event_booking;
CREATE TABLE users (...);
ALTER TABLE users ADD COLUMN age INT;
DROP TABLE users;These modify the schema, not the data itself.
#CREATE TABLE
A production-style users table:
CREATE TABLE users (
user_id BIGINT AUTO_INCREMENT PRIMARY KEY,
full_name VARCHAR(100) NOT NULL,
email VARCHAR(150) UNIQUE NOT NULL,
phone VARCHAR(15),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);Why These Data Types?
| Column type | Why? |
|---|---|
BIGINT | Supports millions/billions of records |
VARCHAR | Variable-length strings save space |
TIMESTAMP | Automatically stores the time (DEFAULT / ON UPDATE CURRENT_TIMESTAMP) |
AUTO_INCREMENT | Generates IDs automatically |
Behind the Scenes
When MySQL receives CREATE TABLE users (...), it stores metadata — table name, columns, data types, constraints and indexes — in its data dictionary, and creates the table's storage (for InnoDB, a .ibd tablespace file by default).
#ALTER TABLE
Real projects evolve constantly. Suppose your manager says "We also need date of birth." No need to recreate the table:
-- Add a column
ALTER TABLE users
ADD COLUMN date_of_birth DATE;
-- Rename a column
ALTER TABLE users
RENAME COLUMN phone TO mobile_number;
-- Modify the data type
ALTER TABLE users
MODIFY mobile_number VARCHAR(20);
-- Drop a column
ALTER TABLE users
DROP COLUMN date_of_birth;#DELETE vs TRUNCATE vs DROP
One of the most asked interview questions.
DELETE
DELETE FROM users;Removes rows. ✅ Can use WHERE. ✅ Can be rolled back (inside a transaction with InnoDB). The AUTO_INCREMENT counter is not reset.
TRUNCATE
TRUNCATE TABLE users;Deletes all rows, very fast, and resets the AUTO_INCREMENT counter. ❌ Can't filter rows. It behaves like a DDL operation — it causes an implicit commit, so it can't be rolled back, and it fails on a table referenced by a foreign key.
DROP
DROP TABLE users;Deletes the data, the table structure, its indexes and its constraints. Everything is gone.
Comparison
| Feature | DELETE | TRUNCATE | DROP |
|---|---|---|---|
| Removes data | ✓ | ✓ | ✓ |
| Removes the table | ✗ | ✗ | ✓ |
WHERE allowed | ✓ | ✗ | ✗ |
Resets AUTO_INCREMENT | ✗ | ✓ | N/A |
| Can be rolled back | ✓ (in a transaction) | ✗ | ✗ |
| Table exists afterwards | ✓ | ✓ | ✗ |
| Speed on large tables | Slow (row by row) | Fast | Fast |
#INSERT
-- Single row
INSERT INTO users (full_name, email)
VALUES ('Rahul', 'rahul@gmail.com');
-- Multiple rows
INSERT INTO users (full_name, email)
VALUES ('Raj', 'raj@gmail.com'),
('Ankit', 'ankit@gmail.com'),
('Amit', 'amit@gmail.com');#UPDATE
UPDATE users
SET full_name = 'Rahul Sharma'
WHERE user_id = 1;UPDATE users SET full_name = 'ABC';#DELETE
-- Delete one record
DELETE FROM users
WHERE user_id = 10;
-- Delete inactive users
DELETE FROM users
WHERE status = 'INACTIVE';Never run DELETE without confirming the WHERE clause, unless you intentionally want to remove all rows.
#SELECT
The most frequently used SQL statement.
-- All users
SELECT *
FROM users;
-- Selected columns
SELECT user_id, full_name, email
FROM users;
-- Alias
SELECT full_name AS customer_name
FROM users;
-- Distinct values
SELECT DISTINCT city
FROM users;
-- Pagination: skip the first 20 rows, return the next 10
SELECT *
FROM users
LIMIT 10 OFFSET 20;#Real Spring Boot Example
User user = new User();
user.setFullName("Rahul");
user.setEmail("rahul@gmail.com");
userRepository.save(user);Hibernate typically generates SQL similar to:
INSERT INTO users (full_name, email)
VALUES (?, ?);Fetching a user with userRepository.findById(1L) becomes something like:
SELECT user_id, full_name, email, ...
FROM users
WHERE user_id = ?;Changing a managed entity (user.setFullName("Rahul Sharma")) results in an UPDATE when the transaction is flushed. Understanding these statements makes it much easier to debug JPA/Hibernate issues.
#Common Mistakes
Using SELECT * Everywhere
-- ❌
SELECT *
FROM users;
-- ✅ Only retrieve the columns you need
SELECT user_id, full_name
FROM users;Forgetting WHERE
UPDATE users SET salary = 0;
DELETE FROM users;These unintentionally affect every row.
Not Specifying Columns in INSERT
-- ❌
INSERT INTO users
VALUES (...);
-- ✅ Protects your code if the table structure changes later
INSERT INTO users (full_name, email)
VALUES (...);#Interview Questions
Q1What is the difference between DDL and DML?
DDL (CREATE, ALTER, DROP, TRUNCATE) changes the database structure; DML (INSERT, UPDATE, DELETE) changes the data.
Q2Explain DELETE, TRUNCATE and DROP.
DELETE removes selected rows (can use WHERE, can be rolled back). TRUNCATE removes all rows quickly, resets AUTO_INCREMENT and can't be rolled back. DROP removes the whole table, including its structure.
Q3Why should we avoid SELECT * in production?
It fetches unnecessary data (more I/O and network traffic), can prevent index-only (covering) reads, and breaks silently when columns are added or reordered.
Q4What happens if UPDATE is executed without a WHERE clause?
Every row in the table is updated.
Q5Why specify column names in INSERT statements?
So the statement keeps working (and stays correct) if columns are added or reordered later.
Q6What is the difference between VARCHAR and CHAR?
CHAR(n) is fixed-length and padded; VARCHAR(n) is variable-length and stores only what's used.
Q7How does Hibernate perform an INSERT?
On save()/persist() it generates a parameterized INSERT INTO table (columns) VALUES (?, ?) and executes it through JDBC when the session is flushed (or immediately, for IDENTITY IDs).
Q8Why is AUTO_INCREMENT useful?
It generates unique primary keys automatically and safely under concurrent inserts.
#Hands-On Assignment
Using the event_booking database (users, events, venues, tickets):
- Insert at least 10 records into each table.
- Update the name of one event.
- Delete one ticket.
- Add a new column
statusto theuserstable. - Change the length of the
phonecolumn. - Retrieve all users; only names and emails; the first five users; and distinct cities (if you add a
citycolumn).
Mini Challenge
Design a movies table with movie ID, movie name, language, duration (minutes), release date, rating and created time. Then insert 5 movies, update one movie's rating, delete one movie, and retrieve all movies released after a chosen date.
#Cheat Sheet
| Command | Purpose |
|---|---|
CREATE | Create database objects |
ALTER | Modify table structure |
DROP | Remove a database object permanently |
TRUNCATE | Remove all rows quickly |
INSERT | Add new rows |
UPDATE | Modify existing rows |
DELETE | Remove rows |
SELECT | Read data |
LIMIT | Restrict the number of rows returned |
OFFSET | Skip a specified number of rows |