Skip to content
Happy Programming Guide
Start learning
Web Development

Working with Databases: A Beginner’s Introduction

What a database is, the SQL you actually need, and the one rule about building queries that separates safe code from a security hole.

Two SODIMM RAM modules installed on a laptop motherboard with nearby cooling components

A database stores data so it survives your program closing, and lets you ask questions of it without loading everything into memory.

SQL
SELECT name, email FROM users WHERE active = 1 ORDER BY name;

That is SQL — the language nearly every database speaks. It reads almost like English, which is deliberate.

The model#

A relational database is a set of tables. Each table has columns (the fields) and rows (the records). One column is the primary key — a value unique to each row, usually called id.

Output
users
 id | name | email
----+------+------------------
  1 | Ada  | ada@example.com
  2 | Sam  | sam@example.com

orders
 id | user_id | total
----+---------+-------
  1 |       1 |   450
  2 |       1 |   120

orders.user_id is a foreign key pointing at users.id. That is the whole idea behind “relational” — you store each fact once and connect tables by id rather than repeating the name in every order.

The five statements#

SQL
-- Read
SELECT name, email FROM users WHERE active = 1 ORDER BY name LIMIT 10;

-- Create
INSERT INTO users (name, email) VALUES ('Ada', 'ada@example.com');

-- Update
UPDATE users SET active = 0 WHERE id = 2;

-- Delete
DELETE FROM users WHERE id = 2;

-- Combine tables
SELECT users.name, orders.total
FROM orders
JOIN users ON users.id = orders.user_id;

Grouping and counting#

SQL
SELECT user_id, COUNT(*) AS order_count, SUM(total) AS spent
FROM orders
GROUP BY user_id
HAVING SUM(total) > 500
ORDER BY spent DESC;

WHERE filters rows before grouping; HAVING filters the groups afterwards. Mixing those up is the most common SQL confusion after joins.

The rule that matters most#

Never build a query by joining strings with user input. This is SQL injection, and it is how databases get emptied.

Python
# Never do this
cursor.execute(f"SELECT * FROM users WHERE name = '{name}'")

# Do this — the database keeps the value separate from the query
cursor.execute("SELECT * FROM users WHERE name = ?", (name,))
PHP
<?php
// PHP with PDO
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = :name");
$stmt->execute(["name" => $name]);
?>

With a placeholder, the database treats the value as data and never as instructions — no matter what it contains. There is no situation where string-joining is the right answer.

A worked example in Python#

SQLite needs no server and stores everything in one file, which makes it ideal for learning:

Python
import sqlite3

with sqlite3.connect("shop.db") as conn:
    conn.execute("""
        CREATE TABLE IF NOT EXISTS users (
            id    INTEGER PRIMARY KEY,
            name  TEXT NOT NULL,
            email TEXT NOT NULL UNIQUE
        )
    """)

    conn.execute(
        "INSERT OR IGNORE INTO users (name, email) VALUES (?, ?)",
        ("Ada", "ada@example.com"),
    )

    for row in conn.execute("SELECT id, name FROM users ORDER BY name"):
        print(row)

Which one to start with#

Database Good for
SQLite Learning, small apps. One file, no server, built into Python.
PostgreSQL Real projects. Strict, capable, widely used.
MySQL / MariaDB Very common in web hosting and PHP projects.
MongoDB Document storage rather than tables. Different model — learn SQL first.

Learn on SQLite. The SQL transfers almost unchanged.

Indexes#

Searching a column without an index means checking every row. On a large table that is the difference between instant and slow:

SQL
CREATE INDEX idx_users_email ON users(email);

Index the columns you filter or join on. Do not index everything — each one costs time on every write.

Questions people ask#

What is an ORM?

A library that maps database rows to objects so you write User.find(1) instead of SQL. Convenient, and worth learning SQL first so you can tell what it is doing when something is slow.

SQL or NoSQL?

Start with SQL. Most data is relational, and the concepts transfer. Document databases solve specific problems you have not met yet.

What is a transaction?

A group of changes that all succeed or all fail together — moving money between accounts being the classic example. In Python’s sqlite3, the with block commits on success and rolls back on an exception.

Where do I put the database password?

In an environment variable, never in code, and never committed. See Git and GitHub explained for .gitignore.

Where to go next#

Next lessonBack-end development explained

Keep reading

Web Development

CSS Flexbox Explained

Flexbox lays items out in one direction. Once you understand the main axis, justify-content and align-items stop being guesswork — here is…

4 min read

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *