# What a database is

> **What you will learn**
> How a database differs from a spreadsheet, how to read tables, rows, columns
> and keys, the shape of one line of SQL, and why "read-only account" keeps
> coming up.

## Where a company's facts pile up

Orders, members, stock, payments. Records that grow daily live in a database.
Nearly every number you see on a screen came out of one.

## It is tables

The most common kind — a **relational database** — holds data in tables.

**The `orders` table**

| id | customer_id | ordered_at | amount | status |
|---|---|---|---|---|
| 1001 | 42 | 2026-08-01 | 128000 | paid |
| 1002 | 7 | 2026-08-01 | 34000 | refunded |

| Term | Meaning |
|---|---|
| **Table** | one table — usually one kind of fact |
| **Row** (record) | one line across — one event |
| **Column** (field) | one slot down — one attribute |
| **Primary key** (PK) | the value that names one row — `id` above |
| **Foreign key** (FK) | a value pointing at another table — `customer_id` above |

**Foreign keys are what "relational" means.** Instead of copying the customer's
name into every order, you store the number and fetch the name from the customer
table. So when a customer changes their name, **you change one place.**

```mermaid
graph TD
  A["orders<br/>id · customer_id · amount"] -->|"joined by customer_id"| B["customers<br/>id · name · email"]
```

## How it differs from a spreadsheet

| | Spreadsheet | Database |
|---|---|---|
| Simultaneous edits | conflicts, copies breed | **many people at once** |
| Volume | struggles past a few hundred thousand rows | hundreds of millions |
| Rules | any value goes in | **format, required, uniqueness enforced** |
| Permissions | per file | **per table, per column** |
| History | who changed it? | can be recorded |

**"final.xlsx / final_really.xlsx is breeding" is the signal to move.** Once
copies exist, nobody knows which one is the fact.

## SQL — how you ask a database

A query looks like this. It is close enough to English that **reading it is
learnable.**

```sql
SELECT region, COUNT(*)
FROM returns
WHERE returned_at >= '2026-07-01'
GROUP BY region;
```

| Piece | Meaning |
|---|---|
| `SELECT` | what to show |
| `FROM` | from which table |
| `WHERE` | which rows to keep |
| `GROUP BY` | what to group by |

**Attach a database to an agent and it writes these for you**
([Attaching a database](/guide/cn-database)). Removing the need to know SQL is
the point of that feature.

## Reading and writing are different in kind

| Kind | SQL | Reversible |
|---|---|---|
| Read | `SELECT` | changes nothing |
| Insert | `INSERT` | delete it again |
| Update | `UPDATE` | **the old value is gone** |
| Delete | `DELETE` · `DROP` | **not reversible** |

`UPDATE` and `DELETE` **apply to the whole table when the condition is
missing.** That one-line difference is how every customer gets upgraded at once.

```sql
UPDATE customers SET tier = 'VIP' WHERE id = 42;   -- one person
UPDATE customers SET tier = 'VIP';                 -- everyone. The condition is missing
```

## So you block it with the account

This is why the manual keeps saying "read-only account". Every database account
has **a defined set of things it may do.**

```
✓ Create a new account holding only SELECT, and attach that
✓ Attach a replica or an analytics database rather than production
✗ Attach the account the application uses
```

**Deciding by instruction and blocking by permission are different.**
Instructions can [drift](/guide/ai-hallucination) or be
[overridden by outside input](/guide/mcp-prompt-injection); account permissions
are enforced by the database — the database edition of
[Tools are permissions](/guide/mcp-security).

## Kinds — the names are enough

| Kind | Example | Character |
|---|---|---|
| Relational | PostgreSQL · MySQL | tables and relations. The common case |
| File-based | SQLite | one file is the database |
| Document | MongoDB | stores JSON-like blobs |
| Vector | pgvector and others | **finding things close in meaning** — used by [grounding](/guide/ai-grounding) |

**The last row connects directly to AI.** Sentences are stored as lists of
numbers (embeddings) so you can retrieve "documents close in meaning".

## Backups — check exactly this

```
□ Are backups running
□ Has a restore **ever been tried**
□ How far back can you go
```

**The second line is the real one.** Backups running and restores working are
different facts, and the difference only shows on the day it matters.

## Common misconceptions

### "Our data is all in spreadsheets — can we not use AI?"

**You can.** But [Phase 2 — data and system assessment](/guide/ax-phase2-assessment)
asks "what lives where", and scattered spreadsheets make that step slow.

### "If I attach a database to an agent, does our data leave?"

**Query results feed into producing the answer.** So you narrow what is
reachable (account permissions) and hide values that must not leave with
[masking](/guide/cn-masking).

---

## Check yourself

**1. What does a foreign key do?**

<details>
<summary>Answer</summary>

**Points at a row in another table**, so the same information is not copied
everywhere and one edit is enough.
</details>

**2. The most dangerous mistake with `UPDATE`?**

<details>
<summary>Answer</summary>

**Omitting the `WHERE` condition.** It applies to the entire table and the old
values do not come back.
</details>

**3. Why is a read-only account stronger than a tool setting?**

<details>
<summary>Answer</summary>

**Different enforcer.** Instructions and settings can change; account permissions
are enforced by the database itself.
</details>

---

The last chapter of this part →
[Accounts, passwords, API keys, permissions](/guide/it-accounts)
