Introduction to MySQL
MySQL is one of the world's most popular open-source relational database management systems (RDBMS). It's a key component of the LAMP (Linux, Apache, MySQL, PHP/Perl/Python) stack, which forms the foundation of countless web applications.
Analogy: MySQL as a Digital Library
Think of MySQL as a sophisticated digital library system:
- The MySQL server is like the library building - it houses all the data and controls access
- Databases are like separate collections or sections within the library
- Tables are like specialized bookshelves for different types of books
- Rows are individual books with specific information
- Columns define what information (title, author, publication date) is stored for each book
- Indexes are like the library's card catalog - they help find information quickly
- The SQL language is how you communicate with the librarian to find, add, or modify books
As a developer, you're both the architect designing this library system and the patron retrieving information from it.
Why MySQL?
- Performance: Optimized for high-speed operations and handling large datasets
- Reliability: Proven track record in production environments for decades
- Scalability: Can grow from small applications to enterprise-level systems
- Ease of Use: Straightforward to set up, configure, and manage
- Cross-Platform: Runs on virtually all operating systems
- Community Support: Large community and extensive documentation
- PHP Integration: Excellent native support in PHP, making it ideal for web development
MySQL Variants and Forks
There are several MySQL variants and forks to be aware of:
- MySQL Community Edition: Free, open-source version suitable for most applications
- MySQL Enterprise Edition: Commercial version with additional tools and support
- MariaDB: A community-developed fork created by MySQL's original developers after Oracle's acquisition
- Percona Server: A high-performance, drop-in replacement for MySQL
In this course, we'll focus on MySQL Community Edition, but most concepts apply to all variants.
Installing MySQL
Platform-Specific Installation
Windows Installation
- Download the MySQL Installer from the official MySQL website
- Launch the installer and choose the "Developer Default" or "Server only" setup type
- Follow the installation wizard steps:
- Choose installation location
- Configure the MySQL server (authentication method, root password)
- Configure Windows service settings
- Apply configuration
- Complete the installation
macOS Installation
There are two main methods for installing MySQL on macOS:
Using MySQL Package Installer:
- Download the DMG archive from the MySQL website
- Open the DMG file and run the package installer
- Follow the installation wizard
- Note the temporary root password provided at the end of installation
Using Homebrew (recommended for developers):
# Install Homebrew if you don't have it
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install MySQL
brew install mysql
# Start MySQL service
brew services start mysql
# Secure the MySQL installation
mysql_secure_installation
Linux Installation (Ubuntu/Debian)
# Update package index
sudo apt update
# Install MySQL server
sudo apt install mysql-server
# Start MySQL service
sudo systemctl start mysql
# Enable MySQL to start on boot
sudo systemctl enable mysql
# Run the security script
sudo mysql_secure_installation
Verifying Installation
After installation, verify that MySQL is running correctly:
# Check MySQL version
mysql --version
# Connect to MySQL server
mysql -u root -p
# After entering password, you should see the MySQL prompt:
# mysql>
# Show databases
SHOW DATABASES;
# Exit MySQL client
EXIT;
Troubleshooting Installation Issues
- Connection refused: Ensure the MySQL service is running
- Access denied: Verify your username and password
- Can't connect to MySQL server: Check the server address and port
- No such file or directory: Verify installation path and configuration
For detailed troubleshooting, check the MySQL error log:
- Windows:
C:\ProgramData\MySQL\MySQL Server 8.0\Data\[hostname].err - Linux:
/var/log/mysql/error.log - macOS:
/usr/local/mysql/data/[hostname].error/opt/homebrew/var/mysql/[hostname].err
MySQL Configuration Basics
Proper configuration is essential for security, performance, and functionality. Let's explore the key configuration aspects of MySQL.
The MySQL Configuration File
MySQL's main configuration is stored in a file named my.cnf or my.ini (on Windows). The location varies by platform:
- Windows:
C:\ProgramData\MySQL\MySQL Server 8.0\my.ini - Linux:
/etc/mysql/my.cnfor/etc/my.cnf - macOS:
/usr/local/mysql/my.cnfor/etc/my.cnf
Example my.cnf File:
[mysqld]
# Network settings
port = 3306
bind-address = 127.0.0.1
# Character set and collation
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# InnoDB settings (storage engine)
innodb_buffer_pool_size = 256M
innodb_log_file_size = 64M
# Connection settings
max_connections = 150
wait_timeout = 600
[mysql]
# Client settings
default-character-set = utf8mb4
[client]
# Client connection defaults
port = 3306
default-character-set = utf8mb4
Important Configuration Parameters
| Parameter | Description | Default Value | Recommendation |
|---|---|---|---|
| port | The port MySQL listens on | 3306 | Default is fine for development |
| bind-address | IP address to bind to | 127.0.0.1 | Use 127.0.0.1 for local-only, 0.0.0.0 for all interfaces |
| character-set-server | Default character set | utf8mb4 | Always use utf8mb4 for full Unicode support |
| max_connections | Maximum simultaneous connections | 151 | Increase for high-traffic applications |
| innodb_buffer_pool_size | Memory allocated for data caching | 128M | 50-80% of available RAM for dedicated servers |
| wait_timeout | Time to wait for activity on a connection | 28800 (8 hours) | Lower for web applications (300-600 seconds) |
Configuration Best Practices
- Always make a backup of your configuration file before making changes
- Restart MySQL after configuration changes:
sudo systemctl restart mysql(Linux) or using the service manager - Verify changes took effect with:
SHOW VARIABLES LIKE 'variable_name'; - Start with conservative settings and adjust based on performance metrics
- Use monitoring tools to identify bottlenecks before adjusting configurations
MySQL User Management
Proper user management is crucial for security. MySQL uses a privilege-based security model where each user is granted specific permissions.
Creating and Managing Users
Creating a New User:
-- Create a new user
CREATE USER 'webuser'@'localhost' IDENTIFIED BY 'password123';
-- Grant specific privileges
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'webuser'@'localhost';
-- Or grant all privileges on a database
GRANT ALL PRIVILEGES ON myapp_db.* TO 'webuser'@'localhost';
-- Apply the privilege changes
FLUSH PRIVILEGES;
Modifying User Privileges:
-- Add additional privileges
GRANT CREATE, ALTER ON myapp_db.* TO 'webuser'@'localhost';
-- Revoke privileges
REVOKE DELETE ON myapp_db.* FROM 'webuser'@'localhost';
-- Apply changes
FLUSH PRIVILEGES;
Viewing and Updating User Information:
-- Show all users
SELECT user, host FROM mysql.user;
-- Show grants for a specific user
SHOW GRANTS FOR 'webuser'@'localhost';
-- Change a user's password
ALTER USER 'webuser'@'localhost' IDENTIFIED BY 'newpassword456';
-- Delete a user
DROP USER 'webuser'@'localhost';
The MySQL Privilege System
MySQL's privilege system is hierarchical and granular:
| Privilege Type | Common Privileges | Description |
|---|---|---|
| Data Privileges | SELECT, INSERT, UPDATE, DELETE | Reading and modifying data in tables |
| Structure Privileges | CREATE, ALTER, DROP, INDEX | Creating and modifying database objects |
| Administrative Privileges | GRANT, SUPER, RELOAD, SHUTDOWN | Server administration tasks |
Security Best Practices
- Principle of Least Privilege: Grant only the permissions necessary for each user's function
- Avoid Using 'root': Never use the root account in applications
- Restrict Access: Limit connection hosts (use 'localhost' instead of '%' when possible)
- Strong Passwords: Use complex passwords and consider password validation plugins
- Regular Audits: Periodically review user privileges and remove unnecessary accounts
- Avoid Storing Plaintext Passwords: In code or configuration files
Creating and Managing Databases
Before connecting your PHP application to MySQL, you need to create and structure your database.
Creating a Database
Basic Database Creation:
-- Create a new database
CREATE DATABASE myapp_db;
-- Create with specific character set and collation
CREATE DATABASE myapp_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
Managing Databases:
-- Show all databases
SHOW DATABASES;
-- Switch to a database
USE myapp_db;
-- Check current database
SELECT DATABASE();
-- Delete a database (be careful!)
DROP DATABASE myapp_db;
Creating Tables and Structure
Creating Tables:
-- Create a users table
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- Create a posts table with a foreign key
CREATE TABLE posts (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL,
title VARCHAR(200) NOT NULL,
content TEXT,
published BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
Modifying Tables:
-- Add a new column
ALTER TABLE users ADD COLUMN last_login DATETIME;
-- Modify a column
ALTER TABLE posts MODIFY title VARCHAR(300) NOT NULL;
-- Add an index
CREATE INDEX idx_posts_user_id ON posts(user_id);
-- View table structure
DESCRIBE users;
SHOW CREATE TABLE posts;
-- List all tables
SHOW TABLES;
MySQL Administration Tools
MySQL offers several tools for database administration, both command-line and graphical.
Command-Line Tools
- MySQL Command-Line Client: Interactive interface for executing SQL commands
- mysqladmin: Client for administrative operations
- mysqldump: Utility for creating database backups
- mysqlimport: Data import client
- mysqlcheck: Table maintenance utility
Common MySQL Command-Line Operations:
# Backup a database
mysqldump -u root -p myapp_db > myapp_backup.sql
# Restore from backup
mysql -u root -p myapp_db < myapp_backup.sql
# Check and repair tables
mysqlcheck -u root -p --check myapp_db
mysqlcheck -u root -p --repair myapp_db
# Import data from CSV
mysqlimport -u root -p --fields-terminated-by=',' myapp_db /path/to/data.csv
Graphical Administration Tools
MySQL Workbench
Official tool from MySQL that provides data modeling, SQL development, and comprehensive administration tools.
- Database design and modeling
- SQL development with syntax highlighting
- Server configuration and monitoring
- User administration
- Data import/export
phpMyAdmin
Web-based MySQL administration tool, especially popular in shared hosting environments.
- Web interface for MySQL operations
- Database and table creation/editing
- SQL query execution
- Import/export functionality
- User management
Other Tools
- Adminer: Lightweight alternative to phpMyAdmin
- HeidiSQL: Windows-based MySQL client and admin tool
- DBeaver: Universal database tool with MySQL support
- Sequel Pro/Ace: Native MySQL client for macOS
- TablePlus: Modern, native database client for multiple platforms
Backup and Recovery
Regular backups are essential for data safety. MySQL provides several methods for backing up and restoring databases.
Types of MySQL Backups
- Logical Backups: SQL statements that recreate the database objects and data
- Physical Backups: Copies of the database files, typically faster but less portable
- Full Backups: Complete copy of the database
- Incremental Backups: Only changes since the last backup
- Online Backups: Performed while the database is running
- Offline Backups: Require shutting down the database
Using mysqldump for Backups
The most common method for logical backups is using the mysqldump utility:
Basic Backup Commands:
# Back up a single database
mysqldump -u root -p --opt myapp_db > myapp_backup.sql
# Back up multiple databases
mysqldump -u root -p --databases db1 db2 db3 > multiple_dbs_backup.sql
# Back up all databases
mysqldump -u root -p --all-databases > full_backup.sql
# Create a compressed backup
mysqldump -u root -p myapp_db | gzip > myapp_backup.sql.gz
# Backup only specific tables
mysqldump -u root -p myapp_db users posts > selected_tables_backup.sql
Restoring from Backups:
# Restore a database
mysql -u root -p myapp_db < myapp_backup.sql
# Restore from a compressed backup
gunzip < myapp_backup.sql.gz | mysql -u root -p myapp_db
# Restore multiple databases
mysql -u root -p < multiple_dbs_backup.sql
Backup Best Practices
- Regular Schedule: Implement automated, scheduled backups
- Off-site Storage: Store backups in multiple locations, including off-site
- Test Restores: Regularly test the backup restoration process
- Retention Policy: Define how long to keep different backups
- Documentation: Document the backup and restore procedures
- Monitoring: Verify that backups complete successfully
Automated Backup Script Example (Linux/macOS):
#!/bin/bash
# Simple MySQL backup script
# Configuration
DB_USER="backup_user"
DB_PASS="backup_password"
DB_NAME="myapp_db"
BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
BACKUP_FILE="$BACKUP_DIR/$DB_NAME-$DATE.sql.gz"
# Create backup directory if it doesn't exist
mkdir -p $BACKUP_DIR
# Create backup
mysqldump -u $DB_USER -p$DB_PASS --opt $DB_NAME | gzip > $BACKUP_FILE
# Check if backup was successful
if [ $? -eq 0 ]; then
echo "Backup created successfully: $BACKUP_FILE"
else
echo "Error creating backup" >&2
exit 1
fi
# Remove backups older than 30 days
find $BACKUP_DIR -name "$DB_NAME-*.sql.gz" -mtime +30 -delete
MySQL Performance Basics
Understanding MySQL performance fundamentals will help you build more efficient PHP applications.
Key Performance Factors
- Proper Indexing: Essential for query performance
- Query Optimization: Writing efficient SQL queries
- Server Configuration: Allocating appropriate resources
- Hardware: Adequate CPU, memory, and storage
- Caching: Reducing database load
Basic Indexing
Indexes speed up data retrieval but can slow down writes. They're essential for large tables.
Creating and Managing Indexes:
-- Add an index to a single column
CREATE INDEX idx_username ON users(username);
-- Create a composite index on multiple columns
CREATE INDEX idx_first_last_name ON users(first_name, last_name);
-- Add a UNIQUE index
CREATE UNIQUE INDEX idx_email ON users(email);
-- View existing indexes
SHOW INDEX FROM users;
-- Remove an index
DROP INDEX idx_username ON users;
When to Index
Consider adding indexes on:
- Columns frequently used in WHERE clauses
- Columns used in JOIN conditions
- Columns used in ORDER BY or GROUP BY
Be cautious about over-indexing, as indexes:
- Increase storage space requirements
- Slow down INSERT, UPDATE, and DELETE operations
- Require maintenance
Query Optimization Basics
Efficient vs. Inefficient Queries:
| Inefficient | Efficient | Reason |
|---|---|---|
SELECT * FROM users |
SELECT id, username FROM users |
Only retrieve needed columns |
SELECT * FROM posts WHERE YEAR(created_at) = 2023 |
SELECT * FROM posts WHERE created_at BETWEEN '2023-01-01' AND '2023-12-31' |
Functions on indexed columns prevent index usage |
SELECT * FROM users WHERE username LIKE '%smith%' |
SELECT * FROM users WHERE username LIKE 'smith%' |
Leading wildcards can't use indexes effectively |
SELECT COUNT(*) FROM posts (large table) |
SELECT COUNT(*) FROM posts WHERE created_at > '2023-01-01' |
Limit scope when possible |
Using EXPLAIN to Analyze Queries
The EXPLAIN statement shows how MySQL executes a query, helping you identify performance issues.
Using EXPLAIN:
-- Analyze a SELECT query
EXPLAIN SELECT u.username, p.title
FROM users u
JOIN posts p ON u.id = p.user_id
WHERE p.created_at > '2023-01-01';
Sample EXPLAIN Output:
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
|---|---|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | p | range | created_at_idx | created_at_idx | 5 | NULL | 1043 | Using where |
| 1 | SIMPLE | u | eq_ref | PRIMARY | PRIMARY | 4 | mydb.p.user_id | 1 | NULL |
Understanding EXPLAIN Output
Key fields to look for:
- type: Join type - eq_ref, ref, range, and index are good; ALL indicates a full table scan
- key: The index being used; NULL indicates no index
- rows: Estimated number of rows examined
- Extra: Additional information (Using filesort, Using temporary table can indicate performance issues)
Practical Activities
Activity 1: MySQL Installation and Configuration
- Install MySQL on your development machine
- Secure the installation by running mysql_secure_installation
- Connect to the MySQL server using the command-line client
- Check the MySQL version and status
- Locate and review the MySQL configuration file on your system
Activity 2: Database and User Setup
- Create a new database named "web_dev_course"
- Create a new user named "course_user" with access to the database
- Grant the appropriate privileges to the user (SELECT, INSERT, UPDATE, DELETE)
- Verify the user's privileges
- Connect to the database using the new user account
Activity 3: Create a Blog Database Schema
Design and implement a database for a simple blog application with:
- A users table with id, username, email, password_hash, and registration date
- A posts table with id, user_id, title, content, created_at, and published status
- A comments table with id, post_id, user_id, content, and created_at
- A categories table with id and name
- A post_categories junction table to establish a many-to-many relationship
- Create appropriate indexes for the tables
- Ensure proper foreign key relationships
Key Takeaways
- MySQL is a powerful, open-source relational database ideal for web applications
- Installation steps vary by platform but follow a similar pattern
- Proper configuration is essential for security and performance
- Creating appropriate users with least-privilege permissions enhances security
- Database and table design forms the foundation of your application
- Regular backups are critical for data protection
- Performance optimization starts with proper indexing and query design
- Various administration tools are available for managing MySQL
Next Steps
In our next lecture, we'll dive into PHP and MySQL integration, exploring how to connect your PHP applications to MySQL databases and execute queries from your PHP code.