1 Versioning and Database Research
Benjamin Goisser edited this page 2026-02-06 17:10:15 +01:00

Möglichkeiten

Strategie Was wird gespeichert Pro Con
Versionen jede Version als Snapshot mit Timestamp, Version Gut für Versionierung, Easy implementation Storageproblem, vorallem auch bei Versionen mit minimalen Unterschieden
Delta Storage Delta Updates zwischen Versionen mit State Vectors (Operationen wie inserts, delete usw.) Effizient für Speicher, Granulare Versionierung "Komplex" in Implementierung und auch bei Rekonstruieren von Dokument (alle Operationen in der Reihenfolge anwenden -Laden dauert lange)
Hybrid Volles Dokument periodisch speichern, dazwischen inkremetelle Updates (Bsp. Yjs) Effizient für Read/Write; Leichte Compaction, Gutes Scaling Komplex da sowohl Full als auch Delta, Aufpassen bei Inconsistency zwischen Delta und Last Full Document

Wie könnte das Datenbank-Schema aussehen?

Nur falls wir es tatsächlich von Grund auf selbst machen

CREATE TABLE Document (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  title VARCHAR(255),
  content TEXT,  -- Letze Vollversion
  created_at TIMESTAMP,
  last_modified_at TIMESTAMP
);
-- Der Table nur notwendig für Hybrid Modell sonst verlinkt Dokument z.B. direkt auf Delta
CREATE TABLE DocumentVersion (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  document_id BIGINT,
  version_number INT,
  content TEXT,  -- Vollversion zu bestimmten Zeitpunkt
  user_id VARCHAR(255),
  timestamp TIMESTAMP,
  FOREIGN KEY (document_id) REFERENCES Document(id)
);

CREATE TABLE DocumentDelta (
  id BIGINT AUTO_INCREMENT PRIMARY KEY,
  document_id BIGINT,
  operation_type VARCHAR(255),  -- Type of operation (insert, delete, etc.)
  text TEXT,  -- Text being modified
  position INT,  -- Position of the change
  timestamp TIMESTAMP,
  user_id VARCHAR(255),
  FOREIGN KEY (document_id) REFERENCES Document(id)
);

  • Hybrid: Um den Inhalt eines Dokument dann abzufragen, wird die letzte Vollversion aus der Document-Tabelle genommen und alle Deltas (sortiert nach TIMESTAMP) mit der entsprechenden DocumentId. Die Deltas werden dann auf den Content der letzten Vollversion applied.
  • Delta: Beginnend bei leerem Dokument alle Delta für die DokumentId abrufen und im der Reihenfolge des TIMESTAMPS applien. Dauert halt lange.

Media Types speichern

Drei Arten

  • Image URL (nicht auf eigenen Server) in der Database
    • Effizient und Scalable
    • Schnelles Laden
    • ABER: Einschränkung für User
  • als BLOB in der Database
    • Alles in einer Datenbank
    • ABER: Perfomance und Scaling könnte Problem sein
  • als File im File System
    • Besser optimiert als Datenbank für größere Files
    • Einbindung falls wir Cloud machen
    • ABER: Aufpassen auf File Mgmt und korrektes Linking der Dokumente

Wie könnte das aussehen?

Wenn ein User ein Bild im Dokument einfügt, wird es auf den Server hochgeladen. Danach wird das Bild über eine URL zugänglich gemacht und diese URL im Markdown eingefügt.

CREATE TABLE media_file (
  id UUID PRIMARY KEY,        -- Eindeutige ID für das Bild/Media
  filename TEXT,              -- Name der Datei
  mime_type TEXT,             -- MIME-Type der Datei (z. B. "image/png")
  file_path TEXT,             -- Pfad zur Datei im Dateisystem (z. B. '/uploads/images/image1.png')
  created_at TIMESTAMP,       -- Zeitpunkt der Erstellung
  file_size BIGINT            -- Optional: Dateigröße in Bytes
);

Aufpassen wegen Cleanup

  • Wenn ein Dokument gelöscht wird, alle Bildreferenz im Dokument suchen und Bilder löschen.
  • Garbage-Collection in regelmäßigen Abständen (auch für Dokumente)
  • Bilder die nicht in einer aktuellen Version sind, siehe "Was muss noch geklärt werden"

Anmerkungen

  • Bzgl. y-redis von Nick, aktuell ist Postgres-Implementation auf Vollversionen ausgelegt (falls ich das nicht falsch interpretiere), kann man aber easy ändern. Für Deltas muss man einfach den zuletzt gespeicherten StateVector aus der Datenbank holen und dann encodeStateAsUpdate mit dem StateVector aufrufen.
  • Yjs-Documents zu speichern ziemlich easy. Deltas kann man einfach mit encodeStateAsUpdate und als Argument den zuletzt gespeicherten State Vector abspeichern. Für Snapshots von Vollversionen kann man einfach dann ab bestimmter Anzahl Deltas encodeStateAsUpdate ohne StateVector abspeichern. Alte States kann man dann auch easy wiederherstellen. PROBLEM: Wollen wir History mit welcher User hat was bearbeitet weil das ist in Update nicht vorhanden.
  • Deltas referenzieren nur die letzte Vollversion (bei Hybrid), andere Deltas werden nach Generieren einer Vollversion gelöscht (wegen Cleanup und Effiziente Storage;find ich sinnvoll), dann gehen aber auch Teile der Versionierung verloren. Erlauben wir nur Wiederherstellung bis zu Vollversionen (Deltas könnte man dann z.B. mit reduced Info speichern, um nur die Versionierung noch zu zeigen) oder Full Delta Storage (da halt dann das Problem mit Laden von Dokument indem alle Deltas applied)?
  • Wann speichern wir Daten persistent? (Jede Minute, Manuelle Eingabe, Nach Inaktivität?)
  • Sollen wir Bilder die nicht in einer aktuellen Version sind löschen?