#What a database is and why we use one
AddedA database is an organised collection of data, and a database management system (DBMS) is the program that stores it, guards it and answers questions about it. In everyday speech "the database" means both. MySQL, PostgreSQL, MongoDB and Redis are all DBMSs; the ch01 schema with its customers and orders is a database inside one of them.
You could keep the same data in JSON files and write code to read them. That works until two requests write at once and one overwrites the other, the process crashes halfway through a write and leaves a half-written file, someone stores an order for a customer who doesn't exist, or you need "every customer in Toronto who bought a laptop" and have to write and maintain a loop for it. A DBMS exists to solve those problems once, for every application: safe concurrent access, durability after a crash, rules that the data must obey, and a query language that lets you say what you want instead of how to fetch it.
A good mental model is a librarian with a strict rulebook. You never walk into the stacks yourself. You hand over a request ("all the books by this author"), the librarian works out the fastest way to find them, refuses to shelve a book that breaks the rules, keeps a log so nothing is lost if the lights go out, and makes sure two people borrowing at the same moment don't end up with the same copy.
SELECT DISTINCT p.name AS product
FROM customers c
JOIN orders o ON o.customer_id = c.id
JOIN order_items oi ON oi.order_id = o.id
JOIN products p ON p.id = oi.product_id
WHERE c.name = 'Rohit'
ORDER BY p.name;+---------------------------------------+
| product |
+---------------------------------------+
| Designing Data-Intensive Applications |
| SQL Performance Explained |
| ThinkBook 14 |
| USB-C Charger |
+---------------------------------------+
4 rows in set (0.000 sec)- The question is "which products has Rohit bought?". The answer lives in four tables: the customer is in
customers, his orders inorders, the lines of each order inorder_itemsand the product names inproducts. - The query only describes the result: start from customers, follow each foreign key to the next table, keep the rows where the customer is
Rohit. It says nothing about loops, files or which table to read first. - MySQL's optimizer decides the plan: which table to start from, which indexes to use, in which order to join. The answer is Rohit's two orders (1 and 2), their four order lines and the four product names behind them. With a million customers the plan might be completely different, and the query text would not change.
DISTINCTremoves repeats (if he had bought the same product twice it would appear once) andORDER BYsorts the names alphabetically. WithoutORDER BYthe row order is not guaranteed.- This is the main thing a database gives you over files: one declarative question replaces a hand-written loop, and the engine stays responsible for doing it efficiently.
The other half of the job is protection. The database refuses data that breaks its rules, whoever sends it:
INSERT INTO customers (name, email, city, created_at)
VALUES ('Rohit V', 'rohit@example.com', 'Ottawa', NOW());ERROR 1062 (23000): Duplicate entry 'rohit@example.com' for key 'customers.email'- The
customerstable was created withemail VARCHAR(100) NOT NULL UNIQUE, so MySQL keeps a unique index onemail. - Before writing the new row it looks up
rohit@example.comin that index and finds customer 1 already there. - The whole statement is rejected with error 1062 and SQLSTATE
23000(integrity constraint violation). Nothing is written. - The rule is enforced inside the database, so it holds for every application, script and person that connects, not just the one that remembered to check first.
And it can make several changes all or nothing with a transaction:
START TRANSACTION;
UPDATE products SET stock = stock - 1 WHERE id = 1;
SELECT id, name, stock FROM products WHERE id = 1;
ROLLBACK;
SELECT id, name, stock FROM products WHERE id = 1;Query OK, 0 rows affected (0.000 sec)
Query OK, 1 row affected (0.000 sec)
Rows matched: 1 Changed: 1 Warnings: 0
+----+--------------+-------+
| id | name | stock |
+----+--------------+-------+
| 1 | ThinkBook 14 | 11 |
+----+--------------+-------+
Query OK, 0 rows affected (0.001 sec)
+----+--------------+-------+
| id | name | stock |
+----+--------------+-------+
| 1 | ThinkBook 14 | 12 |
+----+--------------+-------+START TRANSACTIONopens a unit of work. Changes made from now on are provisional.- The
UPDATEtakes the ThinkBook's stock12 → 11. Inside this session the change is visible straight away, so the firstSELECTshows11. ROLLBACKthrows the whole unit away. InnoDB uses its undo log to put the row back as it was.- The second
SELECTshows12again. If the session had crashed instead of rolling back, the result would be the same: an uncommitted change never survives. - This is atomicity, the "A" in ACID. Transactions get their own chapter (Transactions and ACID).
What a DBMS gives you, compared with files you manage yourself:
| Problem | Files and your own code | A DBMS |
|---|---|---|
| Two writers at once | Last write wins, data lost | Locks and MVCC keep both safe |
| Crash mid-write | Half-written file | Write-ahead (redo) log replays or discards it |
| Bad data | Every app must check | Constraints (UNIQUE, FOREIGN KEY, CHECK) checked centrally |
| New question | Write a new loop | Write a new query; the optimizer plans it |
| Large data | Read everything | Indexes find rows without scanning |
| Who may see what | Filesystem permissions | Users, roles and GRANT per table |