Kennisbank › Sqlite Nosql › Documentdatabase: SQLite en NoSQL naast elkaar
sqlite nosql starter 21 September 2026

Documentdatabase: SQLite en NoSQL naast elkaar

Documentdatabase: SQLite en NoSQL naast elkaar Een documentdatabase slaat gegevens op in documenten, meestal in een JSON-achtig formaat, en MongoDB is daarvan

SQLite is één bestand op disk. Geen server, geen poort, geen netwerk. Je applicatie opent het bestand en leest of schrijft. Dat is alles.

MongoDB is een serverproces dat op een poort luistert, replicatie kan doen, sharding kan doen, en een client-library in je applicatie vereist. Dat is meer bewegende delen.

De vuistregel: heb je één proces dat tegelijk schrijft, en past je hele dataset op één schijf? SQLite. Heb je meerdere applicatieservers, hoge schrijflast, of een schema dat per week verandert? MongoDB of een andere documentdatabase.

2. SQLite installeren en een database aanmaken

Op Debian en Ubuntu:

```bash sudo apt update sudo apt install sqlite3 sqlite3 --version ```

Je krijgt iets als `3.45.1`. Alles boven 3.35 is prima; die versie introduceerde `RETURNING` en verbeterde `UPSERT`, wat het leven een stuk dragelijker maakt.

Maak een database:

```bash sqlite3 /var/lib/myapp/data.db ```

Je zit nu in de SQLite-shell. Maak een tabel:

```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, email TEXT NOT NULL UNIQUE, profile JSON );

INSERT INTO users (email, profile) VALUES ('test@example.com', '{"plan": "free", "signup": "2024-01-15"}');

.quit ```

Merk op dat SQLite sinds 3.9 een `JSON`-kolomtype kent en sinds 3.38 ingebouwde JSON-functies heeft. Je kunt dus prima een document in een relationele database stoppen. Dat is precies het punt dat mensen vergeten wanneer ze het als "ouderwets" wegzetten.

3. MongoDB installeren

MongoDB staat niet in de standaard Ubuntu-repositories met een recente versie. Voeg de officiële repo toe. Voor MongoDB 7.0 op Ubuntu 22.04:

```bash sudo apt install -y gnupg curl curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \ sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor

echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \ sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

sudo apt update sudo apt install -y mongodb-org sudo systemctl enable --now mongod ```

Controleer:

```bash systemctl status mongod mongosh --eval 'db.runCommand({ ping: 1 })' ```

Het antwoord moet `{ ok: 1 }` bevatten. Zo niet, kijk dan in `/var/log/mongodb/mongod.log`.

4. Begrijp het verschil in schrijfgedrag

Dit is waar de keuze in de praktijk op stukloopt, niet op features.

SQLite vergrendelt tijdens een schrijfactie het hele databasebestand. Sinds versie 3.7 met WAL-mode kunnen lezers en één schrijver tegelijk werken, maar twee schrijvers nog steeds niet. Voor een webapplicatie met tien gelijktijdige gebruikers is dat meestal prima. Voor honderd niet.

Zet WAL aan zodra je SQLite in productie gebruikt:

```bash sqlite3 /var/lib/myapp/data.db "PRAGMA journal_mode=WAL;" ```

Het antwoord is `wal`. Zonder deze regel is je doorvoer bij gelijktijdige reads dramatisch slechter. Met WAL schrijft SQLite naar een `-wal`-bestand naast de database en checkpoint dat periodiek terug. Vergeet niet beide bestanden te back-uppen — een kopie van alleen `data.db` is een incomplete database.

MongoDB schrijft naar een WiredTiger-storage-engine die document-level locking doet. Twee gebruikers die verschillende documenten aanpassen botsen niet. Dat is de winst, en die winst kost je een serverproces, geheugen, en een replicaset als je niet op één node wilt zitten.

5. Kies je consistentiemodel

SQLite geeft je ACID zonder nadenken. Elke transactie is atomair, consistent, geïsoleerd en duurzaam. Dat is het standaardgedrag, niet een optie die je aanzet.

MongoDB is ACID op documentniveau, en sinds versie 4.0 ook op multi-document-niveau binnen een replicaset. Maar die multi-document-transacties zijn trager dan single-document-writes, en ze werken niet op een standalone node. Wil je ze, dan moet je een replicaset opzetten — ook lokaal voor ontwikkeling.

Dat is een reële kostenpost. Een replicaset voor development op je laptop betekent drie `mongod`-processen of een tool als `mtools`. Voor SQLite is de equivalente stap: niets.

6. Query's schrijven die niet verrassen

In SQLite gebruik je SQL. Je kent het al. `JOIN`, `GROUP BY`, `EXPLAIN QUERY PLAN` — allemaal aanwezig.

```sql EXPLAIN QUERY PLAN SELECT email FROM users WHERE json_extract(profile, '$.plan') = 'free'; ```

Als daar `SCAN` staat in plaats van `SEARCH`, doe je een full table scan. Voor JSON-velden kun je een expression index maken:

```sql CREATE INDEX idx_users_plan ON users(json_extract(profile, '$.plan')); ```

In MongoDB gebruik je de aggregation pipeline:

```javascript db.users.aggregate([ { $match: { "profile.plan": "free" } }, { $project: { email: 1, _id: 0 } } ]) ```

De syntax is anders, de denkwijze ook. MongoDB beloont het embedden van gerelateerde data in één document. SQLite beloont normalisatie en joins. Wie MongoDB gebruikt alsof het tabellen zijn — met references en `$lookup` voor alles — krijgt de slechtste combinatie van beide werelden.

7. Back-up op de juiste manier

Voor SQLite gebruik je nooit `cp` op een draaiende database. Het WAL-bestand kan nog niet gecheckpoint zijn en je krijgt een inconsistente kopie.

Gebruik de online backup-API:

```bash sqlite3 /var/lib/myapp/data.db ".backup '/backup/data-$(date +%F).db'" ```

Dit is veilig tijdens gebruik en blokkeert schrijvers alleen kort.

Voor MongoDB gebruik je `mongodump`:

```bash mongodump --uri="mongodb://localhost:27017" --out=/backup/mongo-$(date +%F) ```

Op een replicaset is `mongodump` prima voor kleine datasets, maar voor grote volumes wil je filesystem snapshots of de `--oplog`-optie voor point-in-time-herstel.

8. Meet voordat je migreert

De meeste teams die van SQLite naar MongoDB gaan, doen dat omdat ze dénken dat het nodig is. Meet eerst.

```bash sqlite3 /var/lib/myapp/data.db "PRAGMA page_count; PRAGMA page_size;" ```

Vermenigvuldig de twee. Dat is je databasegrootte in bytes. Zit je onder de 50 GB en heb je minder dan pakweg 50 schrijfacties per seconde, dan is de kans groot dat SQLite sneller is dan MongoDB op dezelfde hardware. Niet omdat het beter is, maar omdat er geen netwerk tussen je applicatie en de data zit.

Verificatie

Voor SQLite:

```bash sqlite3 /var/lib/myapp/data.db "PRAGMA integrity_check;" ```

Het antwoord moet `ok` zijn. Alles anders betekent corruptie en dan wil je dat gisteren weten.

Voor MongoDB:

```bash mongosh --eval 'db.adminCommand({ serverStatus: 1 }).connections' ```

Je krijgt een object met `current`, `available` en `totalCreated`. Als `available` richting nul gaat, zit je tegen de connection limit aan en moet je of je poolgrootte aanpassen of meer resources geven.

Voor beide: doe een echte query via je applicatie, niet alleen via de shell. De shell vertelt je niets over hoe je ORM of driver met de database praat.

Veelgestelde problemen

SQLite: "database is locked"

Een schrijver houdt de lock vast en een tweede probeert te schrijven. Zet WAL aan (stap 4), verhoog de busy-timeout, of accepteer dat je architectuur niet bij SQLite past.

```bash sqlite3 /var/lib/myapp/data.db "PRAGMA busy_timeout=5000;" ```

Vijf seconden wachten voordat SQLite opgeeft. Dat lost de symptomen op, niet de oorzaak.

MongoDB: "not authorized on admin to execute command"

Je hebt authenticatie aanstaan maar geen user aangemaakt. Maak er één aan via de localhost-exception:

```javascript use admin db.createUser({ user: "admin", pwd: passwordPrompt(), roles: [{ role: "userAdminAnyDatabase", db: "admin" }] }) ```

Daarna in `/etc/mongod.conf` `security.authorization: enabled` zetten en herstarten. Doe dit vóór je MongoDB op een publiek IP zet, niet erna.

SQLite: JSON-query's zijn traag

Zonder expression index doet elke `json_extract` een volledige scan. Maak de index aan zoals in stap 6, of overweeg een gewone kolom voor velden waar je vaak op filtert. JSON in SQLite is handig, maar het is geen vervanging voor een echt schema als je veel op die velden query't.

Tot slot

De keuze tussen SQLite en een documentdatabase is geen keuze tussen oud en nieuw. Het is een keuze tussen één bestand zonder bewegende delen en een serverproces dat je kunt schalen maar ook moet onderhouden. Wie SQLite kiest, kiest voor minder werk en een lagere bovengrens. Wie MongoDB kiest, kiest voor meer bewegende delen en een hogere bovengrens — mits hij ze weet te benutten. De meeste applicaties die een documentdatabase nodig denken te hebben, hebben er geen. De meeste applicaties die er een hebben, hadden er tien jaar geleden geen kunnen gebruiken.

← Terug naar kennisbank
← Terug naar kennisbank