5 Datenbank
Ralf Warmuth edited this page 2026-01-09 22:32:38 +01:00
This file contains ambiguous Unicode characters

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: Name
  • street, postcode, city: Adresse
  • email, phone: Kontakt
  • transfer: Übergabeart
  • teamMember: Name des Teammitglieds (optional)
  • number: Vergebene Anmeldenummer
  • createdAt: 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 Organisators
  • eventDate: 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: Erstellt registrations Tabelle
  • initConfigSchema.sql: Erstellt config Tabelle

Datenzugriff

Repository-Pattern

Alle Datenzugriffe erfolgen über Repositories:

  • RegistrationRepository: Anmeldungen
  • ConfigRepository: Konfiguration

PDO-Verbindung

Erstellt durch Repository::CreatePDO():

$pdo = Repository::CreatePDO(__DIR__ . '/../../data/zwergenboerse.db');

Einstellungen:

  • ERRMODE_EXCEPTION: Exceptions bei Fehlern
  • FETCH_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:

  1. Neue SQL-Datei erstellen
  2. In initSchema() einbinden
  3. 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)