DevNotes
Support
SQL & MySQL · Chapter 02

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.

◷ 7 min read§ 15 sections? 9 interview questions{ } 17 code examples

#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:

CategoryMeaningCommands
DDLData Definition LanguageCREATE, ALTER, DROP, TRUNCATE
DMLData Manipulation LanguageINSERT, UPDATE, DELETE
DQLData Query LanguageSELECT
TCLTransaction Control LanguageCOMMIT, ROLLBACK, SAVEPOINT
DCLData Control LanguageGRANT, REVOKE

Think of it like Java:

SQLJava analogy
DDLDesigning classes
DMLCreating and changing objects
DQLReading objects
TCLUndo / commit changes
DCLAccess control

#DDL (Data Definition Language)

DDL changes the structure of the database:

SQL
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:

SQL
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 typeWhy?
BIGINTSupports millions/billions of records
VARCHARVariable-length strings save space
TIMESTAMPAutomatically stores the time (DEFAULT / ON UPDATE CURRENT_TIMESTAMP)
AUTO_INCREMENTGenerates 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:

SQL
-- 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

SQL
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

SQL
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

SQL
DROP TABLE users;

Deletes the data, the table structure, its indexes and its constraints. Everything is gone.

Comparison

FeatureDELETETRUNCATEDROP
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 tablesSlow (row by row)FastFast

#INSERT

SQL
-- 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

SQL
UPDATE users
SET full_name = 'Rahul Sharma'
WHERE user_id = 1;
SQL
UPDATE users SET full_name = 'ABC';

#DELETE

SQL
-- 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.

SQL
-- 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

Java
User user = new User();
user.setFullName("Rahul");
user.setEmail("rahul@gmail.com");

userRepository.save(user);

Hibernate typically generates SQL similar to:

SQL
INSERT INTO users (full_name, email)
VALUES (?, ?);

Fetching a user with userRepository.findById(1L) becomes something like:

SQL
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

SQL
-- ❌
SELECT *
FROM users;

-- ✅ Only retrieve the columns you need
SELECT user_id, full_name
FROM users;

Forgetting WHERE

SQL
UPDATE users SET salary = 0;
DELETE FROM users;

These unintentionally affect every row.

Not Specifying Columns in INSERT

SQL
-- ❌
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):

  1. Insert at least 10 records into each table.
  2. Update the name of one event.
  3. Delete one ticket.
  4. Add a new column status to the users table.
  5. Change the length of the phone column.
  6. Retrieve all users; only names and emails; the first five users; and distinct cities (if you add a city column).

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

CommandPurpose
CREATECreate database objects
ALTERModify table structure
DROPRemove a database object permanently
TRUNCATERemove all rows quickly
INSERTAdd new rows
UPDATEModify existing rows
DELETERemove rows
SELECTRead data
LIMITRestrict the number of rows returned
OFFSETSkip a specified number of rows