Event Sourcing vs CRUD: Nutzen Sie es für Audits, nicht für Ästhetik_
Event Sourcing ist leistungsstark, wenn Historie wichtig ist, fügt aber echte Komplexität hinzu. Verwenden Sie es, wo Nachvollziehbarkeit und Replay zentrale Anforderungen sind.
Event Sourcing wird auf zwei verschiedene Arten überbewertet.
Eine Gruppe behandelt es als die einzige ernsthafte Möglichkeit, Geschäftssysteme zu modellieren. Eine andere Gruppe weist es als Architektur-Cosplay zurück. Beide liegen falsch.
Event Sourcing ist gerechtfertigt, wenn die Historie der Änderungen Teil des Geschäftswerts ist und nicht nur ein Implementierungsdetail.
Wenn Sie lediglich ein Blog-CMS oder ein einfaches Admin-Panel benötigen, ist CRUD in der Regel die richtige Abstraktion. Wenn Sie ein Hauptbuch, einen auditlastigen Workflow oder ein Gebiet aufbauen, in dem das Rekonstruieren von Entscheidungen wichtig ist, wird Event Sourcing zu einer ernsthaften Option.
Der Kernunterschied
In einem CRUD-Modell ist die aktuelle Zeile die Quelle der Wahrheit.
In einem event-gestützten Modell ist die Quelle der Wahrheit ein nur erweiterbarer Stream von Domain-Events, und der aktuelle Zustand wird aus diesen Events abgeleitet.
Dieser Unterschied klingt auf Papier klein. In der Praxis ändert es jedoch viel.
Ein CRUD-Update:
UPDATE subscriptions
SET plan = 'pro', updated_at = now()
WHERE id = 'sub_123';
Ein event-gestützter Write:
{
"type": "SubscriptionUpgraded",
"subscriptionId": "sub_123",
"previousPlan": "starter",
"newPlan": "pro",
"occurredAt": "2024-03-22T05:23:50Z"
}
Die erste Anweisung sagt Ihnen, was jetzt wahr ist. Die zweite sagt Ihnen, was passiert ist.
Diese Unterscheidung ist wichtig, wenn Prüfer, Supportmitarbeiter oder nachgelagerte Systeme die Reihenfolge benötigen, nicht nur das Ergebnis.
Warum Teams danach greifen
Event Sourcing verdient seine Komplexität, wenn Sie eine Kombination von Folgendem benötigen:
- einem starken Audit-Trail
- Wiederholbarkeit
- zeitlichen Abfragen wie „was haben wir gestern geglaubt?“
- expliziten Domain-Events für nachgelagerte Verbraucher
Es ist besonders attraktiv, wenn die Änderungshistorie ein Konzept von erster Klasse im Geschäftsbereich ist und nicht nur eine nachträgliche Überlegung.
Warum Teams es bereuen
Die Kosten sind real:
- Sie benötigen Projektionen für effiziente Lesevorgänge
- Schemaevolution wird zu einem fortlaufenden Anliegen
- letztendliche Konsistenz wird Teil der Produkterfahrung
- Betriebliches Debugging wird schwieriger
Ein CRUD-System kann häufig eine Supportanfrage mit einer Abfrage beantworten. Ein event-gestütztes System erfordert möglicherweise ein Verständnis für den Stream, die Projektion und ob die Projektion aktuell ist.
Deshalb sollte Event Sourcing aus geschäftlichen Gründen gewählt werden, nicht weil es eleganter erscheint.
Das Lese-Modell ist nicht optional
Ein reines Ereignisprotokoll ist kein guter allgemeiner Lese-Speicher.
In echten Systemen wird Event Sourcing normalerweise zusammen mit Projektionen oder CQRS-artigen Lese-Modellen verwendet:
type SubscriptionProjection = {
id: string;
currentPlan: string;
status: "active" | "canceled";
renewedAt: string | null;
};
async function handle(event: DomainEvent) {
switch (event.type) {
case "SubscriptionUpgraded":
await db.query(
`UPDATE subscription_projection
SET current_plan = $2
WHERE id = $1`,
[event.subscriptionId, event.newPlan],
);
break;
}
}
Der Ereignisstream bewahrt die Historie. Die Projektion macht das System benutzbar.
Die schwierigen Teile, die niemand überspringt
Wenn Sie Event Sourcing einführen, planen Sie diese von Anfang an:
Ereignisversionierung
Ihr Verständnis des Bereichs wird sich ändern. Alte Events müssen dennoch lesbar bleiben.
Idempotente Verbraucher
Handler müssen doppelte Zustellungen oder Wiederholungen tolerieren.
Projektion Neubauten
Sie benötigen eine sichere Möglichkeit, Lese-Modelle aus dem Quellstream neu zu erstellen.
Betriebliche Sichtbarkeit
Sie müssen wissen, ob eine Projektion aktuell, verzögert oder fehlerhaft ist.
Nichts davon ist theoretisch. Es ist die tägliche betriebliche Oberfläche des Systems.
Eine nützliche Entscheidungsregel
Verwenden Sie CRUD, wenn:
- der aktuelle Zustand das ist, was das Geschäft hauptsächlich interessiert
- Audits mit herkömmlichem Logging behandelt werden können
- das Domain einfach und abfrageintensiv ist
Erwägen Sie Event Sourcing, wenn:
- die Reihenfolge der Änderungen wertvoll ist
- Korrektur und Wiederholung zentrale Workflows sind
- mehrere nachgelagerte Systeme von Domain-Events abhängen
Es geht nicht um architektonische Reife. Es geht um die Passform.
Weitere Lektüre
Verwandte Artikel.
Weiterlesen mit eng verwandten Artikeln zu Software Engineering, Architektur und Implementierungs-Trade-offs.
SQLite Ist Produktionsbereit in der Richtigen Systemform
SQLite ist nicht nur eine Spielzeug-Datenbank, sondern auch kein universeller Ersatz für PostgreSQL. Die Art der Arbeitslast entscheidet, ob es passt.
UUIDv4 vs ULID: Was tatsächlich für Datenbank-Schreibvorgänge wichtig ist
Zufällige Identifikatoren sind praktisch, aber sie sind nicht kostenlos. Wenn die Schreiblokalität von Bedeutung ist, vergleichen Sie UUIDv4 mit zeitlich sortierten Identifikatoren wie ULID oder UUIDv7.