Introduction to Databases
What is a Database?
A Database is an organized collection of structured information or
data, typically stored electronically in a computer system. It's a way to store data in a format
that is easily accessible.
Example: Think of a library where books are organized by topic, author, and title –
that's essentially what a database does with data.
Why Do We Need Databases?
- To store, manage, and retrieve large amounts of data efficiently
- To prevent data duplication and maintain data integrity
- To allow multiple users to access and manipulate data simultaneously
What is SQL?
SQL (Structured Query Language) is the standard programming language
used to communicate with and manipulate databases.
Common Operations (CRUD):
| Operation |
SQL Command |
Description |
| Create |
INSERT |
Add new records |
| Read |
SELECT |
Retrieve data |
| Update |
UPDATE |
Modify existing data |
| Delete |
DELETE |
Remove records |
Comparison with Excel
- In Excel, a sheet is like a table in a database
- Each row in the sheet is similar to a record (or entry) in a database table
- Each column in Excel corresponds to a field (or attribute) in a table
- Excel stores all data in one file, whereas a database can contain multiple related tables
- In databases, you can define strict data types and rules, which Excel doesn't enforce
- Unlike Excel, databases allow complex querying, relationships between tables, and secure
multi-user access
Think of it this way: A database is a more powerful, structured, and scalable
version of Excel for data management.
Relational vs Non-relational Databases
Relational databases store data in structured tables with predefined schemas and relationships
between tables (e.g., MySQL, PostgreSQL). Non-relational databases (NoSQL) use flexible formats like
documents, key-value pairs, or graphs, and don't require a fixed schema (e.g., MongoDB, Firebase).
| Feature |
Relational (SQL) |
Non-relational (NoSQL) |
| Structure |
Tables (rows & columns) |
Documents, Key-Value |
| Language |
SQL |
Varies (Mongo Query, etc.) |
| Schema |
Fixed schema |
Flexible schema |
| Examples |
MySQL, PostgreSQL |
MongoDB, Firebase |
What is DBMS?
A Database Management System (DBMS) is software that interacts with
users, applications, and the database itself to capture and analyze data.
- Examples: MySQL, PostgreSQL, Oracle Database, SQLite
- Functions: Data storage, retrieval, security, backup, and recovery
What is MySQL?
MySQL is an open-source relational database management system (RDBMS) that uses SQL.
- Widely used in web development
- High performance and reliability
- Powers platforms like WordPress, Facebook (early days), and YouTube
Real-World Use Cases:
- E-commerce websites to store customer orders and product listings
- Banking systems to handle transactions securely
- Social networks to manage user data, messages, and posts
Creating a Database in MySQL
Creating a Database
CREATE DATABASE database_name;
CREATE DATABASE student_db;
Tips:
- Database names should be unique
- Avoid using spaces or special characters
- Use lowercase and underscores (_) for better readability (e.g., employee_records)
Viewing All Databases
SHOW DATABASES;
Switching to a Database
Before working with tables, you must select the database:
USE student_db;
Dropping a Database
⚠️ Warning: This action is irreversible! This will permanently delete all data and
tables in the database.
DROP DATABASE database_name;
DROP DATABASE student_db;
Creating Tables in MySQL
Basic Syntax
CREATE TABLE table_name (
column1 datatype constraints,
column2 datatype constraints,
...
);
Example: Creating a Students Table
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL DEFAULT 'No Name',
age INT,
email VARCHAR(100) UNIQUE,
admission_date DATE
);
Explanation:
id INT AUTO_INCREMENT PRIMARY KEY – A unique identifier for each student that
auto-increments
name VARCHAR(100) NOT NULL – Name must be provided
age INT – Stores numeric values for age
email VARCHAR(100) UNIQUE – Each email must be different
admission_date DATE – Stores the date of admission
Commonly Used Data Types
| Data Type |
Description |
Example Usage |
| INT |
Whole numbers |
age, quantity |
| VARCHAR(n) |
Variable-length string |
names, emails |
| TEXT |
Long text strings |
descriptions |
| DATE |
Date values (YYYY-MM-DD) |
birth dates |
| DATETIME |
Date and time values |
timestamps |
| BOOLEAN |
TRUE or FALSE |
flags |
Common Constraints
| Constraint |
Description |
| PRIMARY KEY |
Uniquely identifies each record |
| NOT NULL |
Ensures the column cannot be left empty |
| UNIQUE |
Ensures all values in a column are different |
| AUTO_INCREMENT |
Automatically increases numeric values |
| DEFAULT |
Sets a default value for the column |
| FOREIGN KEY |
Enforces relationships between tables |
Viewing Table Information
SHOW TABLES;
DESCRIBE students;
SELECT * FROM students;
Modifying Tables in MySQL
Renaming a Table
RENAME TABLE old_table_name TO
new_table_name;
Dropping a Table
⚠️ Warning: This permanently deletes the table and all its data!
DROP TABLE table_name;
Renaming a Column
ALTER TABLE table_name
RENAME COLUMN old_column_name TO
new_column_name;
Adding a Column
ALTER TABLE table_name
ADD COLUMN column_name datatype constraints;
ALTER TABLE students
ADD COLUMN gender VARCHAR(10);
Dropping a Column
ALTER TABLE table_name
DROP COLUMN column_name;
Modifying a Column
ALTER TABLE table_name
MODIFY COLUMN column_name new_datatype new_constraints;
ALTER TABLE students
MODIFY COLUMN name VARCHAR(150) NOT NULL;
Changing Column Order
ALTER TABLE table_name
MODIFY COLUMN column_name datatype AFTER
another_column_name;
đź’ˇ Tip: Always review changes on production databases carefully. Use
DESCRIBE table_name to verify structure before and after modifications.
Inserting Data into Tables
Insert One Row
INSERT INTO student (id, name, age, grade, date_of_birth)
VALUES (1, 'Ayesha Khan', 16, '10th', '2007-05-15');
Insert Multiple Rows at Once
INSERT INTO student (id, name, age, grade) VALUES
(15, 'Ayesha Khan', 16, '10th'),
(25, 'Ravi Sharma', 17, '11th'),
(35, 'Meena Joshi', 15, '9th'),
(45, 'Arjun Verma', 18, '12th'),
(55, 'Sara Ali', 16, '10th');
Verify Inserted Records
SELECT * FROM student;
đź’ˇ Tip: Inserting multiple rows at once is more efficient than inserting them one
by one.
Selecting Data from Tables
Basic SELECT Statement
SELECT * FROM student;
SELECT name, grade FROM student;
Using WHERE Clause
SELECT * FROM student
WHERE grade = '10th';
SELECT * FROM student
WHERE age > 16;
Comparison Operators
| Operator |
Description |
Example |
| = |
Equals |
WHERE age = 16 |
| != or <>
|
Not equal to |
WHERE grade != '12th' |
| > |
Greater than |
WHERE age > 16 |
|
<< /td>
| Less than |
WHERE age < 17 |
| >= |
Greater than or equal |
WHERE age >= 16 |
|
<=< /td>
| Less than or equal |
WHERE age <= 18 |
| BETWEEN |
Within a range (inclusive) |
WHERE age BETWEEN 15 AND 17 |
| IN |
Matches any in a list |
WHERE grade IN ('10th', '12th') |
| NOT IN |
Excludes list items |
WHERE grade NOT IN ('9th', '11th') |
| LIKE |
Pattern matching |
WHERE name LIKE 'A%' |
Handling NULL Values
Common Mistake: WHERE grade = NULL will NOT work!
SELECT * FROM student
WHERE grade IS NULL;
SELECT * FROM student
WHERE grade IS NOT NULL;
Combining Conditions
SELECT * FROM student
WHERE grade = '10th' AND age > 16;
SELECT * FROM student
WHERE grade = '9th' OR grade = '12th';
SELECT * FROM student
WHERE (grade = '10th' OR grade = '11th') AND age >= 16;
Sorting Results with ORDER BY
SELECT * FROM student
ORDER BY age ASC;
SELECT * FROM student
ORDER BY name DESC;
Limiting Results with LIMIT
SELECT * FROM student
LIMIT 5;
SELECT * FROM student
LIMIT 2, 5;
Using Wildcards with LIKE
Wildcards:
% – Matches zero or more characters
_ – Matches exactly one character
SELECT * FROM students
WHERE name LIKE 'A%';
SELECT * FROM attendance
WHERE date LIKE '____-__-05';
WHERE date LIKE '2025-05-%';
WHERE date LIKE '____-01-01';
Updating Data in Tables
Basic Syntax
UPDATE table_name
SET column1 = value1, column2 = value2
WHERE condition;
Update a Single Row
UPDATE student
SET grade = '12th'
WHERE id = 2;
Update Multiple Columns
UPDATE student
SET age = 17, grade = '10th'
WHERE id = 3;
Update All Rows
⚠️ Warning: This will modify every row in the table!
UPDATE student
SET age = 18;
Conditional Updates
UPDATE student
SET grade = '10th'
WHERE grade = '9th';
UPDATE student
SET age = age + 1
WHERE age < 18;
Update Using IS NULL
UPDATE student
SET grade = 'Unknown'
WHERE grade IS NULL;
Verify the Update
SELECT * FROM student;
Deleting Data from Tables
Basic Syntax
DELETE FROM table_name
WHERE condition;
⚠️ Important: If you omit the WHERE clause, all rows in the table will be
deleted!
Delete a Specific Row
DELETE FROM student
WHERE id = 2;
Delete Based on Conditions
DELETE FROM student
WHERE grade = '9th';
DELETE FROM student
WHERE age < 16;
DELETE FROM student
WHERE grade IS NULL;
Delete All Rows
DELETE FROM student;
Completely Remove the Table
DROP TABLE student;
Difference:
DELETE FROM removes all rows but keeps the table structure
DROP TABLE removes both the data and the table structure
Transactions: AUTOCOMMIT, COMMIT, and ROLLBACK
What is a Transaction?
A transaction is a sequence of one or more SQL statements executed as a single unit. Transactions
have four key properties (ACID):
- Atomicity: All or nothing
- Consistency: Valid state before and after
- Isolation: Transactions do not interfere
- Durability: Changes persist after commit
AUTOCOMMIT
By default, MySQL runs in autocommit mode. Every SQL statement is treated as a separate
transaction and committed automatically.
SELECT @@autocommit;
SET autocommit = 0;
SET autocommit = 1;
COMMIT
The COMMIT statement permanently saves all changes made in the current transaction.
START TRANSACTION;
UPDATE accounts SET balance = balance
- 100 WHERE id = 1;
UPDATE accounts SET balance = balance
+ 100 WHERE id = 2;
COMMIT;
ROLLBACK
The ROLLBACK statement undoes changes made in the current transaction.
START TRANSACTION;
UPDATE accounts SET balance = balance
- 100 WHERE id = 1;
ROLLBACK;
Best Practices
- Always use transactions when performing multiple related operations
- Disable autocommit when working with critical data updates
- Rollback if any step in your transaction fails
- Test your transactions thoroughly before running them on production data
Date and Time Functions
Getting Current Date and Time
SELECT CURRENT_DATE;
SELECT CURRENT_TIME;
SELECT CURRENT_TIMESTAMP;
SELECT NOW();
SELECT LOCALTIME;
SELECT LOCALTIMESTAMP;
Using in Table Inserts
INSERT INTO logs (event, created_at)
VALUES ('data_import', NOW());
Date and Time Functions Recap
| Function |
Returns |
Example Output |
| CURRENT_DATE |
Date only |
2025-05-02 |
| CURRENT_TIME |
Time only |
14:23:45 |
| NOW() |
Date and time |
2025-05-02 14:23:45 |
| CURDATE() |
Current date |
2025-05-02 |
| CURTIME() |
Current time |
14:23:45 |
SQL Constraints
Constraints are rules applied to table columns to enforce data integrity, consistency, and
validity.
Why Use Constraints?
- Ensure data quality and reliability
- Prevent invalid, duplicate, or null data
- Maintain business rules directly in the database layer
NOT NULL Constraint
Ensures that a column cannot contain NULL values.
CREATE TABLE employees (
id INT NOT NULL,
name VARCHAR(100) NOT NULL
);
UNIQUE Constraint
Ensures that all values in a column are distinct (no duplicates).
CREATE TABLE users (
username VARCHAR(50) UNIQUE,
email VARCHAR(100) UNIQUE
);
DEFAULT Constraint
Sets a default value for a column if none is provided during insert.
CREATE TABLE products (
name VARCHAR(100),
status VARCHAR(20) DEFAULT 'in_stock'
);
CHECK Constraint
Validates that values in a column meet a specific condition.
CREATE TABLE accounts (
id INT,
balance DECIMAL(10,2) CHECK (balance
>= 0)
);
Naming Constraints
CREATE TABLE students (
roll_no INT PRIMARY KEY,
age INT CONSTRAINT chk_age CHECK (age
>= 5),
email VARCHAR(100) UNIQUE
);
Constraint Summary
| Constraint |
Purpose |
| NOT NULL |
Disallow null values |
| UNIQUE |
Disallow duplicate values |
| DEFAULT |
Set default value if none given |
| CHECK |
Enforce value conditions |
| PRIMARY KEY |
Uniquely identify each record |
| FOREIGN KEY |
Establish relationships between tables |
Foreign Keys
What is a Foreign Key?
A foreign key is a column (or set of columns) that establishes a link between data in two tables.
Creating Tables with Foreign Keys
CREATE TABLE classes (
class_id INT AUTO_INCREMENT PRIMARY KEY,
class_name VARCHAR(50) NOT NULL
);
CREATE TABLE students (
student_id INT AUTO_INCREMENT PRIMARY KEY,
student_name VARCHAR(100) NOT NULL,
class_id INT,
FOREIGN KEY (class_id) REFERENCES
classes(class_id)
ON UPDATE CASCADE
ON DELETE SET NULL
);
Understanding Referential Actions
ON UPDATE CASCADE
If the value in the parent table is updated, the corresponding foreign key value in the child
table is automatically updated.
UPDATE classes SET class_id = 10 WHERE class_id = 1;
ON DELETE SET NULL
If a row in the parent table is deleted, the foreign key in the child table will be set to NULL.
DELETE FROM classes WHERE class_id =
2;
Other Referential Actions
| Action |
Description |
| ON DELETE CASCADE |
Deletes the child rows when parent row is deleted |
| ON DELETE RESTRICT |
Prevents deletion if any child rows exist |
| ON DELETE NO ACTION |
Same as RESTRICT in MySQL |
| ON DELETE SET NULL |
Sets foreign key to NULL when parent is deleted |
Viewing Foreign Keys
SHOW CREATE TABLE students;
SELECT
table_name,
column_name,
constraint_name,
referenced_table_name,
referenced_column_name
FROM information_schema.key_column_usage
WHERE referenced_table_name IS NOT
NULL
AND table_schema = 'school';
MySQL Joins
Joins are used to combine data from multiple tables based on a related column.
INNER JOIN
Returns only rows that have matching values in both tables.
SELECT students.name, marks.subject, marks.score
FROM students
INNER JOIN marks ON students.id =
marks.student_id;
LEFT JOIN
Returns all rows from the left table, and matching rows from the right table. If no match, NULL
is returned.
SELECT students.name, marks.subject, marks.score
FROM students
LEFT JOIN marks ON students.id =
marks.student_id;
RIGHT JOIN
Returns all rows from the right table, and matching rows from the left table.
SELECT students.name, marks.subject, marks.score
FROM students
RIGHT JOIN marks ON students.id =
marks.student_id;
CROSS JOIN
Combines every row in the first table with every row in the second table.
SELECT students.name, marks.subject
FROM students
CROSS JOIN marks;
Join Types Summary
| Join Type |
What it does |
| INNER JOIN |
Only rows with a match in both tables |
| LEFT JOIN |
All rows from left table, with matched data if any |
| RIGHT JOIN |
All rows from right table, with matched data if any |
| CROSS JOIN |
All combinations of rows from both tables |
Using UNION
The UNION operator combines result sets of two or more SELECT statements into a single result.
Basic UNION
SELECT name, city FROM customers
UNION
SELECT name, city FROM vendors;
Requirements for UNION
- Same number of columns in all SELECT statements
- Compatible data types in corresponding columns
- Columns are matched by position, not by name
UNION vs UNION ALL
Key Difference:
UNION removes duplicate rows
UNION ALL keeps all rows including duplicates (faster)
SELECT name FROM students
UNION ALL
SELECT name FROM alumni;
Sorting Combined Results
SELECT name FROM students_2023
UNION
SELECT name FROM students_2024
ORDER BY name;
When to Use
- Use UNION if you want a clean list without duplicates
- Use UNION ALL if you want better performance and don't care about
duplicates
MySQL Functions
String Functions
SELECT CONCAT('Hello', ' ', 'World') AS greeting;
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM users;
SELECT LENGTH('Harry');
SELECT UPPER('hello');
SELECT LOWER('MySQL');
SELECT REPLACE('abc', 'b', 'x');
SELECT TRIM('
hello ');
Numeric Functions
SELECT ROUND(12.6789, 2);
SELECT FLOOR(5.9);
SELECT CEIL(5.1);
SELECT ABS(-10);
SELECT MOD(10, 3);
Date Functions
SELECT DATEDIFF('2025-06-01', '2025-05-01');
SELECT YEAR(NOW());
SELECT MONTHNAME('2025-05-03');
SELECT DAY('2025-05-03');
SELECT DATE(NOW());
Aggregate Functions
SELECT COUNT(*) FROM students;
SELECT AVG(score) FROM marks;
SELECT SUM(score) FROM marks;
SELECT MIN(score) FROM marks;
SELECT MAX(score) FROM marks;
Other Useful Functions
SELECT IFNULL(NULL, 'N/A');
SELECT COALESCE(NULL, '', 'Hello');
SELECT RAND();
MySQL Views
What is a View?
A View is like a virtual table. It doesn't store data by itself
but shows data from one or more tables through a saved SQL query.
Why Use Views?
- To simplify complex queries by giving them a name
- To hide sensitive columns from users
- To show only specific rows/columns from a table
- To reuse common query logic across your app or reports
Creating a View
CREATE VIEW public_employees AS
SELECT name, department, salary
FROM employees;
Using a View
SELECT * FROM public_employees;
SELECT * FROM public_employees
WHERE department = 'IT';
Updating a View
CREATE OR REPLACE VIEW public_employees AS
SELECT name, department
FROM employees;
Dropping a View
DROP VIEW public_employees;
Important Notes:
- Views don't store data. If the underlying table changes, the view reflects that
automatically
- Not all views are updatable. Simple views usually are, but complex ones may not allow
INSERT, UPDATE, or DELETE
MySQL Indexes
What is an Index?
An index is a data structure that makes data retrieval
faster—especially when using WHERE, JOIN, ORDER BY, or searching large tables.
Think of it like: The index in a book—instead of reading every page, MySQL uses
the index to jump straight to the relevant row(s).
Why Use Indexes?
- Speed up queries that search, filter, or sort data
- Improve performance for frequent lookups or joins
- Enhance scalability of your database over time
Creating an Index
CREATE INDEX idx_email ON
users(email);
CREATE INDEX idx_name_city ON
users(name, city);
Dropping an Index
DROP INDEX idx_email ON users;
Viewing Indexes
SHOW INDEX FROM users;
When to Use Indexes
- A column is often used in WHERE, JOIN, or ORDER BY clauses
- You're searching by unique fields like email, username, or ID
- You're filtering large tables for specific values regularly
- You want to improve performance of lookups and joins
When NOT to Use Indexes
- The table is small (MySQL can scan it quickly anyway)
- The column is rarely used in searches or filtering
- You're indexing a column with very few unique values
- You're inserting or updating very frequently (indexes slow down writes)
⚠️ Warning: Overusing indexes or indexing the wrong columns can hurt
performance. Use them wisely based on how your data is queried.
Subqueries in MySQL
What is a Subquery?
A subquery is a query nested inside another SQL query. It helps
you perform complex filtering, calculations, or temporary data shaping.
Subquery in WHERE Clause
SELECT name, salary
FROM employees
WHERE salary > (
SELECT AVG(salary)
FROM employees
);
Subquery in FROM Clause
SELECT department, avg_salary
FROM (
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
) AS dept_avg
WHERE avg_salary > 50000;
Subquery in SELECT Clause
SELECT name,
(SELECT COUNT(*)
FROM projects
WHERE projects.employee_id = employees.id) AS project_count
FROM employees;
Correlated Subqueries
A correlated subquery depends on the outer query. It runs once for each row in the outer query.
SELECT name, department, salary
FROM employees e
WHERE salary > (
SELECT AVG(salary)
FROM employees
WHERE department = e.department
);
Types of Subqueries
| Type |
Description |
| Scalar Subquery |
Returns a single value |
| Row Subquery |
Returns one row with multiple columns |
| Table Subquery |
Returns multiple rows and columns |
| Correlated Subquery |
Refers to the outer query inside the subquery |
GROUP BY in MySQL
What is GROUP BY?
The GROUP BY clause groups rows that have the same values in
specified columns. It's usually combined with aggregate functions like COUNT(), SUM(), AVG(),
MAX(), or MIN().
Basic GROUP BY
SELECT department, COUNT(*) AS total_employees
FROM employees
GROUP BY department;
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
GROUP BY with Multiple Columns
SELECT department, job_title, COUNT(*)
AS count
FROM employees
GROUP BY department, job_title;
The HAVING Clause
HAVING is like WHERE, but it works after the grouping is done. It filters groups based on
aggregate results.
SELECT department, COUNT(*) AS total
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;
WHERE vs HAVING
| Clause |
Used For |
Example |
| WHERE |
Filters rows before grouping |
WHERE salary > 50000 |
| HAVING |
Filters groups after grouping |
HAVING AVG(salary) > 60000 |
Using Both WHERE and HAVING
SELECT department, AVG(salary) AS avg_salary
FROM employees
WHERE status = 'active'
GROUP BY department
HAVING AVG(salary) > 60000;
Execution Order:
- WHERE filters rows
- GROUP BY groups them
- HAVING filters the groups
Stored Procedures
What is a Stored Procedure?
A Stored Procedure is a saved block of SQL code that you can
execute later by calling its name—just like a function in programming.
Why Use Stored Procedures?
- To avoid repeating the same SQL logic in multiple places
- To improve performance by reducing network traffic
- To encapsulate complex business logic inside the database
Creating a Simple Procedure
Why change the DELIMITER?
MySQL ends a command at the first semicolon (;). Since stored procedures contain multiple SQL
statements (each ending in ;), we need to tell MySQL not to end the procedure too early. So we
temporarily change the delimiter to something else—then switch it back.
DELIMITER //
CREATE PROCEDURE list_employees()
BEGIN
SELECT * FROM employees;
END //
DELIMITER ;
Calling a Stored Procedure
CALL list_employees();
Procedure with Parameters
DELIMITER //
CREATE PROCEDURE get_employee_by_id(IN
emp_id INT)
BEGIN
SELECT * FROM employees
WHERE id = emp_id;
END //
DELIMITER ;
CALL get_employee_by_id(3);
Dropping a Stored Procedure
DROP PROCEDURE IF EXISTS get_employee_by_id;
Best Practices
- Always give clear names to procedures
- Use IN, OUT, or INOUT for flexible parameter handling
- Keep business logic in the database only if it improves clarity or performance
- Document complex procedures for easier maintenance