This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Datenbank-Dokumentation
Übersicht
Das System verwendet SQLite als Datenbank. Die Datenbank wird automatisch beim ersten Zugriff erstellt.
Datenbank-Datei
Pfad: public/data/zwergenboerse.db
Berechtigungen: Verzeichnis muss beschreibbar sein (chmod 755/775)
Schema
Tabelle: registrations
Speichert alle Anmeldungen.
CREATE TABLE registrations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
salutation TEXT NOT NULL,
firstName TEXT NOT NULL,
lastName TEXT NOT NULL,
street TEXT NOT NULL,
postcode TEXT NOT NULL,
city TEXT NOT NULL,
email TEXT NOT NULL,
phone TEXT NOT NULL,
transfer TEXT NOT NULL,
teamMember TEXT,
number INTEGER NOT NULL,
createdAt TEXT NOT NULL
);
Felder:
id: Primärschlüssel (Auto-Increment)salutation: Anrede (Herr, Frau, Divers)firstName,lastName: Namestreet,postcode,city: Adresseemail,phone: Kontakttransfer: ÜbergabeartteamMember: Name des Teammitglieds (optional)number: Vergebene AnmeldenummercreatedAt: Zeitstempel (Format:d.m.Y H:i:s)
Indizes/Constraints: Neben PRIMARY KEY werden im Code-Schema zusätzliche Indizes/Constraints angelegt (z.B. UNIQUE auf number sowie Indizes auf number/email/createdAt) – siehe zgb-backend/Repository/Schema/Registration/initRegistrationSchema.sql.
Tabelle: mail_queue
Speichert asynchrone Mail-Jobs für den Cron-Worker.
Wichtig: Es werden keine Mail-Bodies gespeichert, sondern nur (registration_number, mail_type) referenziert – Rendering passiert beim Senden.
Schema/Indizes liegen hier:
zgb-backend/Repository/Schema/MailQueue/initMailQueueSchema.sql
Siehe auch: Mail-Queue
Tabelle: config
Speichert System-Konfiguration als Key-Value-Paare.
CREATE TABLE IF NOT EXISTS config (
`key` TEXT PRIMARY KEY,
`value` TEXT NOT NULL
);
Struktur:
key: Konfigurationsschlüssel (z.B.startDate,endDate,adminPasswordHash)value: Konfigurationswert (als Text gespeichert)
Verwendete Keys:
startDate: Startdatum Anmeldung (Format:Y-m-d)endDate: Enddatum Anmeldung (Format:Y-m-d)startNumber: Erste vergebene Nummer (als String)maxNumber: Maximale Anzahl Anmeldungen (als String)operatorEmail: E-Mail des OrganisatorseventDate: Datum der Zwergenbörse (Format:Y-m-d)adminPasswordHash: Gehashtes Admin-Passwort
Hinweis: Die Konfiguration wird als Key-Value-Paare gespeichert, nicht als einzelne Zeile. Das ermöglicht flexible Erweiterungen.
SQL-Dateien
SQL-Schemas sind in separaten Dateien organisiert:
Repository/Schema/
├── Config/
│ ├── initConfigSchema.sql
│ ├── getConfig.sql
│ └── setConfig.sql
└── Registration/
├── initRegistrationSchema.sql
├── saveRegistration.sql
├── getRegistration.sql
├── getAllRegistrations.sql
└── clearAllRegistrations.sql
Schema-Initialisierung
Beim ersten Zugriff auf ein Repository wird automatisch das Schema initialisiert:
public function __construct(PDO $pdo) {
$this->initSchema();
}
Die initSchema() Methode führt die SQL-Datei aus:
initRegistrationSchema.sql: ErstelltregistrationsTabelleinitConfigSchema.sql: ErstelltconfigTabelle
Datenzugriff
Repository-Pattern
Alle Datenzugriffe erfolgen über Repositories:
RegistrationRepository: AnmeldungenConfigRepository: Konfiguration
PDO-Verbindung
Erstellt durch Repository::CreatePDO():
$pdo = Repository::CreatePDO(__DIR__ . '/../../data/zwergenboerse.db');
Einstellungen:
ERRMODE_EXCEPTION: Exceptions bei FehlernFETCH_ASSOC: Assoziative Arrays
Backup & Wartung
Backup
Manuell:
cp public/data/zwergenboerse.db backup/zwergenboerse_$(date +%Y%m%d).db
Automatisiert:
- Cron-Job für regelmäßige Backups
- Vor wichtigen Aktionen (z.B. vor Löschen)
Datenbank prüfen
SQLite CLI:
sqlite3 public/data/zwergenboerse.db
Abfragen:
-- Anzahl Anmeldungen
SELECT COUNT(*) FROM registrations;
-- Alle Anmeldungen
SELECT * FROM registrations;
-- Konfiguration (alle Keys)
SELECT * FROM config;
-- Einzelner Konfigurationswert
SELECT value FROM config WHERE `key` = 'startDate';
Datenbank reparieren
SQLite hat eingebaute Reparatur-Funktionen:
sqlite3 public/data/zwergenboerse.db "PRAGMA integrity_check;"
Datenbank leeren
Vorsicht: Unwiderruflich!
DELETE FROM registrations;
Oder über Admin-Interface (nur außerhalb Anmeldezeitraum)
Migrationen
Aktuell keine Migrationen nötig. Bei Schema-Änderungen:
- Neue SQL-Datei erstellen
- In
initSchema()einbinden - Alte Datenbank manuell migrieren (falls nötig)
Performance
Optimierungen
- Indizes: SQLite erstellt automatisch für PRIMARY KEY
- VACUUM: Regelmäßig ausführen für Optimierung
Weitere Projekt-Optimierungen (Connection-Pooling, PRAGMAs, Caches, etc.) sind hier beschrieben:
VACUUM;
Größen-Limits
SQLite unterstützt:
- Max. Dateigröße: ~140 TB
- Max. Zeilen: Praktisch unbegrenzt
- Für diesen Use-Case: Keine Limits relevant
Sicherheit
Datei-Berechtigungen
chmod 644 public/data/zwergenboerse.db
chmod 755 public/data/
.htaccess Schutz
<FilesMatch "\.(db|sqlite3?)$">
Require all denied
</FilesMatch>
SQL-Injection-Schutz
- Prepared Statements: Alle Queries verwenden Prepared Statements
- Input-Validierung: Vor Datenbank-Zugriff
Troubleshooting
Datenbank nicht beschreibbar
Fehler: Database directory is not writable
Lösung:
chmod 755 public/data
chown www-data:www-data public/data
Datenbank-Datei nicht gefunden
Fehler: Could not open database file
Lösung:
- Verzeichnis
public/data/erstellen - Berechtigungen prüfen
Locked Database
Fehler: database is locked
Lösung:
- Andere Prozesse beenden
- Datenbank-Datei prüfen (
.db-wal,.db-shm)
Einstieg
Architektur
- Architektur-Übersicht
- Frontend-Build
- Backend
- Datenbank
- Mail-Queue
- Performance & Optimierungen
- Entscheidungen & Historie
Betrieb
Projektarbeit
- Code:
ssh://forgejo@home.schumbi.de/ralf/zgb_www.git - Wiki:
ssh://forgejo@home.schumbi.de/ralf/zgb_www.wiki.git