What is a database?
The organised storage layer behind every web application.
Relational (SQL)
Data lives in tables with rows and columns. Tables connect via keys. Examples: MySQL, PostgreSQL, SQLite.
Non-relational (NoSQL)
Stores documents, key-value pairs, or graphs. Flexible schema. Examples: MongoDB, Redis, Firebase.
Key concepts
1
Database
The container — like a filing cabinet. One server can hold many databases.
2
Table
A sheet inside the cabinet. Each table holds one type of data: users, products, orders.
3
Row / Record
One entry — e.g. a single user's information.
4
Column / Field
An attribute of the data — e.g. name, email, created_at.
5
Primary key
A unique ID column (usually id) that identifies every row. Never duplicated, never null.
Create database & table
Run these MySQL commands to set up your database.
1
Log in to MySQL
Open terminal and connect as root.
mysql -u root -p -- Enter root password when prompted
2
Create the database
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE myapp_db;
3
Create the users table
CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(150) UNIQUE NOT NULL, password VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
4
CRUD operations
INSERT INTO users (name, email, password) VALUES ('Alice', 'alice@ex.com', 'hashed'); SELECT * FROM users; UPDATE users SET name='Alicia' WHERE id=1; DELETE FROM users WHERE id=1;
Create user & grant privileges
Never use root in your app. Create a limited database user.
Using root in your web app is dangerous. A dedicated user limits damage if your app is ever compromised.
1
Create the user
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongP@ssw0rd!';
2
Grant all privileges on your DB
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost'; FLUSH PRIVILEGES;
3
Or grant minimal privileges only
GRANT SELECT, INSERT, UPDATE, DELETE ON myapp_db.* TO 'myapp_user'@'localhost'; FLUSH PRIVILEGES; SHOW GRANTS FOR 'myapp_user'@'localhost';
config.php — connect to the database
One file holds all credentials. Every page includes it.
MySQLi version
Beginner<?php $conn = mysqli_connect( 'localhost', 'myapp_user', 'StrongP@ssw0rd!', 'myapp_db' ); if (!$conn) die(mysqli_connect_error()); mysqli_set_charset($conn, "utf8mb4"); ?>
PDO version
Recommended<?php $dsn = "mysql:host=localhost; dbname=myapp_db;charset=utf8mb4"; try { $pdo = new PDO($dsn, 'myapp_user', 'StrongP@ssw0rd!', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION] ); } catch (PDOException $e) { die('DB error.'); } ?>
Use it in any page
require_once 'config.php'; $stmt = $pdo->prepare("SELECT * FROM users WHERE id=?"); $stmt->execute([$_GET['id']]); $user = $stmt->fetch();
Never expose config.php to the browser. Add
Deny from all in .htaccess for the directory containing it.Full app example
A working register / login / dashboard flow with sessions.
myapp/
├── config.php
├── index.php
├── register.php
├── login.php
├── dashboard.php
├── logout.php
└── assets/ (css, js)
register.php
require_once 'config.php'; if($_SERVER['REQUEST_METHOD']==='POST'){ $hash = password_hash( $_POST['password'], PASSWORD_DEFAULT ); $s = $pdo->prepare( "INSERT INTO users (name,email,password) VALUES(?,?,?)" ); $s->execute([ $_POST['name'], $_POST['email'], $hash ]); header('Location: login.php'); }
login.php
session_start(); require_once 'config.php'; if($_SERVER['REQUEST_METHOD']==='POST'){ $s=$pdo->prepare( "SELECT * FROM users WHERE email=?" ); $s->execute([$_POST['email']]); $u=$s->fetch(); if($u && password_verify( $_POST['password'],$u['password'] )){ $_SESSION['user_id']=$u['id']; header('Location: dashboard.php'); } else { $error='Invalid credentials'; } }
dashboard.php — protect a page
session_start(); if(!isset($_SESSION['user_id'])){ header('Location: login.php'); exit(); } require_once 'config.php'; $s=$pdo->prepare("SELECT * FROM users WHERE id=?"); $s->execute([$_SESSION['user_id']]); $user=$s->fetch(); // Output: Welcome, <?= htmlspecialchars($user['name']) ?>!
Architecture — how it all connects
The request flows from browser all the way to the database and back.
Browser
⇄
Web server
Apache/Nginx
⇄
PHP files
config.php
⇄
MySQL
myapp_db
HTTP request → executes PHP → PDO query → rows returned → HTML response
Security checklist
- Use prepared statements — never concatenate user input into SQL.
- Hash all passwords with password_hash() — never store plain text.
- Escape all output with htmlspecialchars() to prevent XSS.
- Never use root for the app DB connection — use a dedicated user.
- Keep config.php private — deny HTTP access via .htaccess.
- Use HTTPS in production — never transmit passwords over plain HTTP.