MySQL Setup and Administration

Getting Started with MySQL Database for Web Development

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?

graph TD M[MySQL] --- C[Community Edition] M --- E[Enterprise Edition] C --- MDB[MariaDB] C --- P[Percona Server] E --- CT[Commercial Tools] E --- CP[Commercial Plugins] E --- CS[Commercial Support] style M fill:#336791,stroke:#333,stroke-width:2px,color:#fff style C fill:#80b1d3,stroke:#333 style E fill:#fb8072,stroke:#333

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

  1. Download the MySQL Installer from the official MySQL website
  2. Launch the installer and choose the "Developer Default" or "Server only" setup type
  3. Follow the installation wizard steps:
    • Choose installation location
    • Configure the MySQL server (authentication method, root password)
    • Configure Windows service settings
    • Apply configuration
  4. Complete the installation

macOS Installation

There are two main methods for installing MySQL on macOS:

Using MySQL Package Installer:
  1. Download the DMG archive from the MySQL website
  2. Open the DMG file and run the package installer
  3. Follow the installation wizard
  4. 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].err or /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:

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:

graph TD R[Root/Global Privileges] --- D[Database-Level Privileges] D --- T[Table-Level Privileges] T --- C[Column-Level Privileges] style R fill:#f9f,stroke:#333,stroke-width:2px
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;
          
Sample Database Structure users id (PK) username email password_hash created_at updated_at posts id (PK) user_id (FK) title content published created_at 1:N

MySQL Administration Tools

MySQL offers several tools for database administration, both command-line and graphical.

Command-Line Tools

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

Download MySQL Workbench

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

Learn more about phpMyAdmin

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

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

  1. Regular Schedule: Implement automated, scheduled backups
  2. Off-site Storage: Store backups in multiple locations, including off-site
  3. Test Restores: Regularly test the backup restoration process
  4. Retention Policy: Define how long to keep different backups
  5. Documentation: Document the backup and restore procedures
  6. 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

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

  1. Install MySQL on your development machine
  2. Secure the installation by running mysql_secure_installation
  3. Connect to the MySQL server using the command-line client
  4. Check the MySQL version and status
  5. Locate and review the MySQL configuration file on your system

Activity 2: Database and User Setup

  1. Create a new database named "web_dev_course"
  2. Create a new user named "course_user" with access to the database
  3. Grant the appropriate privileges to the user (SELECT, INSERT, UPDATE, DELETE)
  4. Verify the user's privileges
  5. 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:

  1. A users table with id, username, email, password_hash, and registration date
  2. A posts table with id, user_id, title, content, created_at, and published status
  3. A comments table with id, post_id, user_id, content, and created_at
  4. A categories table with id and name
  5. A post_categories junction table to establish a many-to-many relationship
  6. Create appropriate indexes for the tables
  7. Ensure proper foreign key relationships

Key Takeaways

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.