# Les 7: Database Principles

---

## Hoofdstuk
**Deel 2: Technical Foundations** (Les 4-8)

## Beschrijving
Leer de basisprincipes van relationele databases voordat we Supabase gaan gebruiken. Begrijp tabellen, relaties, keys en normalisatie - essentiële kennis voor elke developer.

---

## Te Behandelen

### Wat is een Relationele Database?

**Een database is:** Een georganiseerde verzameling van data.

**Relationeel betekent:** Data is opgeslagen in tabellen die aan elkaar gerelateerd zijn.

**Vergelijk het met Excel:**
- Database = Excel workbook
- Tabel = Excel sheet
- Kolom = Excel kolom (field)
- Rij = Excel rij (record)

---

### Tabellen, Kolommen en Rijen

**Voorbeeld: Users tabel**

| id | name | email | created_at |
|----|------|-------|------------|
| 1 | Tim | tim@email.com | 2024-01-15 |
| 2 | Anna | anna@email.com | 2024-01-16 |
| 3 | Jan | jan@email.com | 2024-01-17 |

**Terminologie:**
- **Tabel:** users
- **Kolommen:** id, name, email, created_at
- **Rijen:** 3 records (Tim, Anna, Jan)
- **Cell:** Eén specifieke waarde (bijv. "tim@email.com")

---

### Data Types

Elke kolom heeft een type:

| Type | Beschrijving | Voorbeeld |
|------|--------------|-----------|
| `text` / `varchar` | Tekst | "Tim", "Hello world" |
| `integer` / `int` | Hele getallen | 1, 42, -5 |
| `decimal` / `numeric` | Decimalen | 19.99, 3.14 |
| `boolean` | True/False | true, false |
| `timestamp` | Datum + tijd | 2024-01-15 14:30:00 |
| `uuid` | Unieke identifier | a1b2c3d4-e5f6-... |

**Kies het juiste type:**
- Prijs? → `decimal` (niet `integer`, want centen)
- Is actief? → `boolean`
- Naam? → `text`
- Aantal? → `integer`

---

### Primary Keys

**Wat:** Een kolom die elke rij UNIEK identificeert.

**Regels:**
- Moet uniek zijn per rij
- Mag nooit NULL zijn
- Verandert nooit

**Voorbeeld:**
```
users
------
id (PRIMARY KEY)  | name  | email
1                 | Tim   | tim@email.com
2                 | Anna  | anna@email.com
```

**Waarom niet `email` als primary key?**
- Emails kunnen veranderen
- `id` is stabiel en snel

---

### Foreign Keys

**Wat:** Een kolom die verwijst naar de primary key van een andere tabel.

**Voorbeeld: Posts tabel**
```
posts
------
id | title          | user_id (FOREIGN KEY → users.id)
1  | "Mijn blog"    | 1
2  | "Hello world"  | 1
3  | "Tips"         | 2
```

**Wat zegt dit?**
- Post 1 en 2 zijn van user 1 (Tim)
- Post 3 is van user 2 (Anna)

---

### Relatie Types

**One-to-Many (1:N)** - Meest voorkomend!
```
Eén user → meerdere posts
Eén category → meerdere products
```

**One-to-One (1:1)** - Zeldzaam
```
Eén user → één profile
```

**Many-to-Many (N:N)** - Via tussentabel
```
Posts ↔ Tags (een post heeft meerdere tags, een tag heeft meerdere posts)
```

---

### One-to-Many Voorbeeld

```
users                      posts
------                     ------
id | name                  id | title      | user_id
1  | Tim       ←────────── 1  | "Blog 1"   | 1
2  | Anna      ←────┬───── 2  | "Blog 2"   | 1
                    └───── 3  | "Tips"     | 2
```

**Lees:** Tim heeft 2 posts, Anna heeft 1 post.

---

### Many-to-Many met Tussentabel

```
posts                post_tags              tags
------               ---------              ------
id | title           post_id | tag_id       id | name
1  | "React tips"    1       | 1            1  | "react"
2  | "CSS guide"     1       | 2            2  | "frontend"
                     2       | 2            3  | "css"
                     2       | 3
```

**Lees:**
- Post 1 heeft tags: react, frontend
- Post 2 heeft tags: frontend, css

---

### Normalisatie Basics

**Probleem: Data duplicatie**
```
orders (SLECHT)
------
id | customer_name | customer_email    | product_name | price
1  | Tim           | tim@email.com     | Laptop       | 999
2  | Tim           | tim@email.com     | Phone        | 699
3  | Anna          | anna@email.com    | Laptop       | 999
```

**Problemen:**
- Tim's email staat 2x (als hij verandert: 2 plekken updaten)
- "Laptop" en prijs staan 2x

---

### Genormaliseerde Versie

```
users                  products              orders
------                 --------              ------
id | name  | email     id | name   | price   id | user_id | product_id
1  | Tim   | tim@...   1  | Laptop | 999     1  | 1       | 1
2  | Anna  | anna@...  2  | Phone  | 699     2  | 1       | 2
                                             3  | 2       | 1
```

**Voordelen:**
- Elk gegeven staat 1x
- Update op 1 plek
- Minder opslagruimte

---

### NULL Values

**NULL = "geen waarde" (niet 0, niet "")**

```
users
------
id | name | phone
1  | Tim  | 0612345678
2  | Anna | NULL        ← Geen telefoon bekend
```

**Wanneer NULL toestaan?**
- Optionele velden (phone, description)
- Niet bij verplichte velden (name, email)

---

### Defaults

**Automatische waarde als je niks opgeeft:**

```
todos
------
id | title        | completed | created_at
   |              | DEFAULT: false | DEFAULT: now()
```

Bij `INSERT INTO todos (title) VALUES ('Test')`:
```
id | title  | completed | created_at
1  | Test   | false     | 2024-01-15 10:30:00
```

---

### Database Schema Tekenen

**Tools:** draw.io, Excalidraw, pen en papier

**Conventie:**
```
┌──────────────┐         ┌──────────────┐
│    users     │         │    posts     │
├──────────────┤         ├──────────────┤
│ id (PK)      │───┐     │ id (PK)      │
│ name         │   │     │ title        │
│ email        │   └────→│ user_id (FK) │
│ created_at   │         │ content      │
└──────────────┘         │ created_at   │
                         └──────────────┘
```

PK = Primary Key
FK = Foreign Key
Pijl = Relatie richting

---

## Tools
- Pen en papier / Excalidraw / draw.io
- Supabase Table Editor (vooruitblik)

---

## Lesopdracht (2 uur)

### Database Design Oefening

**Deel 1: Blog Database Ontwerpen (45 min)**

Ontwerp een database voor een blog met:
- Users (kunnen posts schrijven)
- Posts (hebben een auteur)
- Comments (op posts, door users)

Voor elke tabel:
1. Teken de tabel met kolommen
2. Bepaal data types
3. Markeer Primary Keys
4. Markeer Foreign Keys
5. Teken de relaties

**Deel 2: Normalisatie Oefening (30 min)**

Gegeven deze "slechte" tabel:

```
library
-------
book_title | author_name | author_email | borrower_name | borrowed_date
"1984"     | "Orwell"    | orwell@...   | "Tim"         | 2024-01-15
"1984"     | "Orwell"    | orwell@...   | "Anna"        | 2024-01-10
"Dune"     | "Herbert"   | herbert@...  | "Tim"         | 2024-01-12
```

Normaliseer naar aparte tabellen:
1. Welke entiteiten zie je?
2. Maak aparte tabellen
3. Voeg relaties toe

**Deel 3: Eindproject Schema (45 min)**

Ontwerp het database schema voor jouw eindproject:
1. Welke entiteiten heb je nodig?
2. Teken elke tabel met kolommen
3. Bepaal relaties
4. Documenteer je keuzes

### Deliverable
- Blog database schema (tekening)
- Genormaliseerde library database
- Eindproject database schema

---

## Huiswerk (2 uur)

### Verdieping en Voorbereiding

**Deel 1: Eindproject Schema Uitwerken (1 uur)**

Werk je database schema volledig uit:

1. **Per tabel:**
   - Naam
   - Alle kolommen met data types
   - Primary key
   - Foreign keys
   - Defaults
   - Nullable fields

2. **Documenteer:**
   - Waarom deze structuur?
   - Welke relaties?
   - Eventuele alternatieve overwegingen

**Deel 2: Supabase Account (30 min)**

Bereid je voor op volgende les:
1. Maak account op [supabase.com](https://supabase.com)
2. Verken de interface
3. Bekijk de Table Editor

**Deel 3: Reflectie (30 min)**

Beantwoord deze vragen (kort):
1. Wat is het verschil tussen primary en foreign key?
2. Waarom normaliseren we data?
3. Wanneer gebruik je one-to-many vs many-to-many?
4. Welke tabellen heeft jouw eindproject nodig?

### Deliverable
- Volledig uitgewerkt database schema voor eindproject
- Supabase account aangemaakt
- Reflectie vragen beantwoord

---

## Leerdoelen
Na deze les kan de student:
- Uitleggen wat een relationele database is
- Tabellen, kolommen en rijen beschrijven
- De juiste data types kiezen
- Primary keys en hun doel uitleggen
- Foreign keys en relaties begrijpen
- One-to-many en many-to-many relaties herkennen
- Het probleem van data duplicatie identificeren
- Een database normaliseren
- NULL values en defaults begrijpen
- Een database schema ontwerpen en tekenen
