ArchivBlick verwaltet 268.000 Fotos und Videos mit sechs verschiedenen Datenquellen — nicht aus Zufall, sondern aus Überzeugung. Jede Quelle löst ein spezifisches Problem: SQLite für Zero-Setup auf dem Laptop, PostgreSQL mit pgvector für semantische KI-Suche, PostGIS für Karten-Queries, separate Blob-Stores für Thumbnails und Filmstrips, und Cloud-CDN für verteilte Originaldateien. Dieser Beitrag erklärt, warum das kein Over-Engineering ist — sondern eine bewusste Produktstrategie.
Das Problem: Eine Datenbank für alles?
Die meisten Foto-Apps wählen eine Datenbank und bleiben dabei. Immich setzt auf PostgreSQL, PhotoPrism auf MariaDB, Apple Fotos auf SQLite. Das funktioniert — bis es nicht mehr funktioniert.
ArchivBlick ist anders entstanden. Es war nie ein Greenfield-Projekt mit sauberem Schema-Design am Whiteboard. Es ist aus einem realen Problem gewachsen: 268.000 Dateien aus 20 Jahren, verteilt auf Festplatten, NAS, iCloud und SharePoint. Diese Realität erzwingt Flexibilität in der Datenhaltung.
Die zentrale Frage war nie "Welche Datenbank?", sondern: "Welche Datenbank für welches Problem?"
Die sechs Datenquellen im Überblick
Quelle 1: PostgreSQL — das Kraftwerk
Die PostgreSQL-Instanz auf dem Mac mini ist das Herzstück von ArchivBlick. Hier laufen alle Features, die über einfaches Browsen hinausgehen:
PostgreSQL + Erweiterungen
| Erweiterung | Funktion | Praxis-Beispiel |
|---|---|---|
| pgvector | Vektor-Ähnlichkeitssuche (HNSW) | "Fotos ähnlich wie dieses Strandbild" |
| PostGIS | Geo-Queries, Radius-Suche | "Alle Fotos im Umkreis von 5 km um Positano" |
| pg_trgm | Fuzzy-Textsuche, Trigramme | "motorad" findet trotzdem "Motorrad" |
Was PostgreSQL hier von SQLite unterscheidet, ist nicht die Grundfunktion — beide können Tabellen und Abfragen. Es sind die drei Erweiterungen, die ArchivBlick auf dem Mac mini zu einer völlig anderen App machen:
- Semantische Suche: pgvector speichert 1024-dimensionale Embeddings (BGE-M3) und findet visuell ähnliche Fotos in Millisekunden — ohne dass der Suchbegriff exakt im Text vorkommen muss.
- Kartenbasierte Exploration: PostGIS ermöglicht "zeig mir alle Fotos innerhalb dieses Kartenausschnitts" — ein Feature, das mit SQLite schlicht nicht möglich ist.
- Tippfehler-Toleranz: pg_trgm macht die Suche fehlertolerant. Wer "Küstenstrasse" statt "Küstenstraße" tippt, findet trotzdem die richtigen Fotos.
Quelle 2: SQLite — die Universalwaffe
SQLite ist keine Notlösung und kein Kompromiss. Es ist eine bewusste Architekturentscheidung für einen spezifischen Einsatzfall: das lokale Gerät ohne Server, ohne Installation, ohne Konfiguration.
SQLite (Lite-Modus)
Warum das wichtig ist: Nicht jeder ArchivBlick-Nutzer betreibt einen Server. Ein Fotograf, der seine 50.000 Bilder auf dem MacBook durchsuchen will, braucht keine PostgreSQL-Installation. Er braucht eine Datei, die er auf eine externe Festplatte kopieren kann.
SQLite liefert genau das: Eine einzelne Datei, die die komplette Datenbank enthält. Kein Daemon, kein Port, kein Passwort. pip install archivblick && archivblick start — fertig.
SQLite-Modus (Lite)
- Galerie und Thumbnail-Browsing
- Volltext-Suche in Beschreibungen
- Filter nach Datum, Kamera, Archiv
- Lightbox mit EXIF-Daten
- Video-Filmstrips mit Scrubbing
PostgreSQL-Modus (Voll)
- Alles aus Lite, plus:
- Semantische Vektorsuche (pgvector)
- Geo-Suche auf Karte (PostGIS)
- Fuzzy-Suche mit Tippfehler-Toleranz
- Reisebericht-Generator mit Wetter
- KI-basiertes Foto-Scoring
- Wetter-Daten (Open-Meteo)
Quelle 3: Thumbnail-Blob-Storage
Thumbnails sind kein Metadatum — sie sind Binärdaten. In der SQLite-Variante speichert ArchivBlick sie in einer separaten thumbs.db (4,1 GB), die per ATTACH DATABASE an die Hauptdatenbank angehängt wird.
Im PostgreSQL-Modus liegen Thumbnails dagegen als Dateien im Dateisystem — organisiert in Shards:
~/Archivblick/thumbs/
├── lg/ # 800px — Lightbox
│ ├── 000/ # IDs 0-999
│ ├── 001/ # IDs 1000-1999
│ └── ...
├── md/ # 360px — Galerie-Grid
├── sm/ # 176px — Kompakt-Ansicht
└── xs/ # 80px — Miniatur/Liste Warum zwei Systeme? Weil beide ihre Stärken haben. SQLite-Blobs sind portabel — eine Datei, alles drin, kann auf USB-Stick kopiert werden. Datei-basierte Thumbnails sind schneller, weil der Webserver sie direkt ausliefert, ohne Datenbank-Query.
ArchivBlick löst das mit einer Fallback-Kette: Erst wird im Dateisystem gesucht, dann in der Blob-DB, dann wird versucht, einen Frame aus dem Filmstrip-Sprite zu extrahieren. Der Nutzer merkt davon nichts.
Quelle 4: Filmstrip-Datenbank
Die Filmstrip-DB ist ein Sonderfall: Sie bleibt immer SQLite, auch wenn der Rest auf PostgreSQL läuft. Der Grund ist pragmatisch — Filmstrips werden auf dem GPU-Server generiert und als SQLite-Datei zum Mac mini kopiert. Eine Migration nach PG wäre Aufwand ohne Mehrwert.
Was speichert die Filmstrip-DB?
| Spalte | Inhalt |
|---|---|
hash | Eindeutiger Hash → Dateiname des Sprite-JPGs |
grid | Sprite-Layout, z. B. "5x4" (5 Spalten, 4 Reihen) |
frames | Anzahl extrahierter Frames |
gps_lat/lon | GPS-Position aus Video-Metadaten |
duration | Videolänge in Sekunden |
Filmstrips ermöglichen das visuelle Scrubbing durch Videos — man fährt mit der Maus über ein Vorschaubild und sieht einzelne Frames, ohne das Video zu laden. Für ein Archiv mit tausenden GoPro- und Drohnenvideos ist das unverzichtbar.
Quelle 5: User-Datenbank
Bewertungen, Farbmarkierungen und Smart Albums gehören nicht in die Hauptdatenbank. Sie sind nutzerspezifisch und schreibbar — während die Medien-DB im Normalbetrieb Read-Only ist.
Die user_data.db ist eine separate SQLite-Datei mit WAL-Modus (Write-Ahead Logging), die unabhängig vom Backend-Typ existiert. Das hat einen strategischen Grund: User-Präferenzen sind portabel. Ein Nutzer kann seine Bewertungen exportieren, auf ein anderes Gerät mitnehmen oder als Backup sichern — unabhängig davon, ob die Hauptdatenbank SQLite oder PostgreSQL ist.
Quelle 6: Cloud-Anbindungen
ArchivBlick verwaltet Dateien, die physisch an verschiedenen Orten liegen:
Externe Datenquellen
| Quelle | Inhalt | Zugriff |
|---|---|---|
| SharePoint | 368.000 Originaldateien (Fuhrmann-Archiv) | Graph API + Search API |
| Degoo CDN | Filmstrip-Sprites als Fallback | JSON-Cache → HTTP-Proxy |
| NAS (Synology) | Lokale Kopien + Thumbnails | SMB/Dateisystem |
| iCloud | 69.000 persönliche Fotos | Lokaler Export (Trooper-Sicherung) |
Die degoo_cdn_map.json ist ein JSON-basierter Cache, der Filmstrip-Hashes auf CDN-URLs mappt. Kein SQL, kein Schema — absichtlich. Cache-Daten ändern sich schnell und haben andere Konsistenz-Anforderungen als Archiv-Metadaten.
Warum nicht einfach alles in eine DB?
Eine berechtigte Frage. Die Antwort hat drei Dimensionen:
Verschiedene Daten haben verschiedene Lebenszyklen.
Archiv-Metadaten ändern sich selten. User-Bewertungen ändern sich ständig. Thumbnails werden einmal geschrieben und nie aktualisiert. Filmstrips kommen in Batches vom GPU-Server. Jede dieser Datenarten hat eigene Konsistenz-, Performance- und Portabilitäts-Anforderungen.
Portabilität ist ein Feature, kein Kompromiss.
Eine SQLite-Datei kann per AirDrop geteilt werden. Eine PostgreSQL-Datenbank nicht. Für den Anwendungsfall "Fotograf zeigt Kunden sein Archiv auf dem iPad" ist das kein theoretischer Vorteil — es ist ein Verkaufsargument.
Skalierung funktioniert in beide Richtungen.
Nicht jeder Nutzer wächst in Richtung PostgreSQL. Manche brauchen dauerhaft nur SQLite — und das ist ein gültiger Produktionseinsatz, kein "Einsteiger-Modus". Andere starten lokal und wechseln später auf PG, wenn sie Vektorsuche oder Geo-Features brauchen.
Was das für Käufer bedeutet
ArchivBlick bietet keine "Standard"- und "Pro"-Version, die sich nur im Preis unterscheiden. Das Backend bestimmt die Features — und der Nutzer wählt das Backend passend zu seinem Setup:
Einzelnutzer / NAS
SQLite-Modus
- Keine Installation nötig
- Läuft auf Mac, NAS, Raspberry Pi
- Datenbank ist eine kopierbare Datei
- Ideal für 1.000–100.000 Fotos
Power-User / Studio
PostgreSQL-Modus
- Semantische KI-Suche
- Geo-basierte Exploration
- Automatische Reiseberichte
- Ideal für 100.000+ Fotos
Team / Agentur
PostgreSQL + Cloud
- Mehrbenutzerzugriff
- SharePoint-Integration
- Zentrale Thumbnail-Pipeline
- Skaliert auf Millionen Dateien
Vergleich mit der Konkurrenz
| Feature | ArchivBlick | Immich | PhotoPrism |
|---|---|---|---|
| Datenbank | SQLite oder PostgreSQL | Nur PostgreSQL | Nur MariaDB |
| Offline-Betrieb | Ja (SQLite-Modus) | Server nötig | Server nötig |
| Vektorsuche | pgvector (144k Embeddings) | CLIP (in-process) | TensorFlow (optional) |
| Geo-Queries | PostGIS (nativer SQL) | In-Memory | Nicht vorhanden |
| Video-Analyse | Filmstrip-Scrubbing + KI | Basis-Thumbnails | Basis-Thumbnails |
| Portabilität | DB als Datei teilbar | Docker-Export | Docker-Export |
| iPad-App | Native SwiftUI | PWA | PWA |
Die Multi-Datenbank-Architektur ist kein technischer Kompromiss — sie ist ArchivBlicks größter Differenzierungsfaktor. Kein anderes Open-Source-Fotoarchiv bietet die Wahl zwischen Zero-Setup (SQLite) und Enterprise-Features (PostgreSQL + Extensions) in derselben App.
Technisch unter der Haube
Ein Detail für technisch Interessierte: Der Wechsel zwischen SQLite und PostgreSQL geschieht über eine einzige Umgebungsvariable:
# SQLite-Modus (Standard)
ARCHIVBLICK_QUELLE=lokal
# PostgreSQL-Modus
ARCHIVBLICK_QUELLE=macmini Im Code übersetzt ein PgConnection-Wrapper SQLite-kompatible SQL-Syntax (?-Platzhalter) automatisch in PostgreSQL-Syntax (%s). Die REST-API-Endpunkte bleiben identisch — das Frontend merkt nicht, welches Backend aktiv ist.
Das ist ein Pattern, das sich auch für andere Projekte eignet: Schreibe deine Queries für SQLite, übersetze automatisch für PostgreSQL. 90 % der SQL-Syntax sind identisch — die verbleibenden 10 % lassen sich mit einem dünnen Wrapper abfangen.
Fazit: Datenbank-Architektur als Produktstrategie
Sechs Datenquellen klingen nach Komplexität. In der Praxis ist es das Gegenteil: Jede Quelle hat genau eine Aufgabe, genau einen Verantwortungsbereich, genau einen Grund zu existieren.
- PostgreSQL — wenn du die volle Kraft brauchst
- SQLite (Haupt) — wenn du null Konfiguration willst
- SQLite (Thumbs) — weil Binärdaten getrennt gehören
- SQLite (Filmstrips) — weil GPU-Batches als Datei kommen
- SQLite (User) — weil Bewertungen portabel sein müssen
- Cloud/CDN — weil Originaldateien verteilt sind
Für Käufer bedeutet das: Du zahlst nicht für Features, die du nicht brauchst. Fang mit SQLite an, wechsle auf PostgreSQL, wenn du bereit bist — deine Daten, deine Bewertungen, deine Struktur bleiben erhalten.