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