Das GitHub-Projekt CQRS.NET enthält einige konkrete Beispiele dafür, wie Sie EventStores in verschiedenen Technologien ausführen können. Zum Zeitpunkt des Schreibens gibt es eine Implementierung in SQL mit Linq2SQL und ein dazugehöriges SQL-Schema , eine für MongoDB , eine für DocumentDB (CosmosDB, wenn Sie in Azure sind) und eine für EventStore (wie oben erwähnt). In Azure gibt es mehr wie Tabellenspeicher und Blob-Speicher, der dem Flatfile-Speicher sehr ähnlich ist.
Ich denke, der Hauptpunkt hier ist, dass sie alle dem gleichen Auftraggeber / Vertrag entsprechen. Sie alle speichern Informationen an einem einzigen Ort / Container / in einer einzigen Tabelle. Sie verwenden Metadaten, um ein Ereignis von einem anderen zu identifizieren, und speichern das gesamte Ereignis so, wie es war - in einigen Fällen serialisiert, in unterstützenden Technologien, wie es war. Je nachdem, ob Sie eine Dokumentendatenbank, eine relationale Datenbank oder sogar eine Flatfile auswählen, gibt es verschiedene Möglichkeiten, um alle die gleiche Absicht eines Ereignisspeichers zu erreichen (es ist nützlich, wenn Sie Ihre Meinung zu irgendeinem Zeitpunkt ändern und feststellen, dass Sie migrieren oder unterstützen müssen mehr als eine Speichertechnologie).
Als Entwickler des Projekts kann ich einige Einblicke in einige der von uns getroffenen Entscheidungen geben.
Erstens haben wir festgestellt (auch bei eindeutigen UUIDs / GUIDs anstelle von Ganzzahlen), dass aus strategischen Gründen sequenzielle IDs aus strategischen Gründen auftreten. Daher war es für einen Schlüssel nicht eindeutig genug, nur eine ID zu haben. Daher haben wir unsere Haupt-ID-Schlüsselspalte mit den Daten / zusammengeführt. Objekttyp, um einen wirklich (im Sinne Ihrer Anwendung) eindeutigen Schlüssel zu erstellen. Ich weiß, dass einige Leute sagen, dass Sie es nicht speichern müssen, aber das hängt davon ab, ob Sie auf der grünen Wiese sind oder mit vorhandenen Systemen koexistieren müssen.
Wir haben uns aus Gründen der Wartbarkeit an einen einzelnen Container / eine Tabelle / eine Sammlung gehalten, aber wir haben mit einer separaten Tabelle pro Entität / Objekt herumgespielt. Wir haben in der Praxis festgestellt, dass entweder die Anwendung "CREATE" -Berechtigungen benötigt (was im Allgemeinen keine gute Idee ist ... im Allgemeinen gibt es immer Ausnahmen / Ausschlüsse) oder jedes Mal, wenn eine neue Entität / ein neues Objekt existiert oder bereitgestellt wurde, neu Lagerbehälter / Tabellen / Sammlungen mussten gemacht werden. Wir fanden, dass dies für die lokale Entwicklung schmerzlich langsam und für Produktionsbereitstellungen problematisch war. Sie mögen nicht, aber das war unsere reale Erfahrung.
Eine andere Sache, an die Sie sich erinnern sollten, ist, dass das Auffordern von Aktion X dazu führen kann, dass viele verschiedene Ereignisse auftreten, sodass Sie alle Ereignisse kennen, die von einem Befehl / Ereignis / was auch immer nützlich ist, generiert werden. Sie können sich auch auf verschiedene Objekttypen erstrecken, z. B. kann das Drücken von "Kaufen" in einem Einkaufswagen dazu führen, dass Konto- und Lagerereignisse ausgelöst werden. Eine konsumierende Anwendung möchte dies alles wissen, daher haben wir eine Korrelations-ID hinzugefügt. Dies bedeutete, dass ein Verbraucher nach allen Ereignissen fragen konnte, die aufgrund seiner Anfrage ausgelöst wurden. Das sehen Sie im Schema .
Insbesondere bei SQL haben wir festgestellt, dass die Leistung zu einem Engpass wurde, wenn Indizes und Partitionen nicht ausreichend verwendet wurden. Denken Sie daran, dass Ereignisse in umgekehrter Reihenfolge gestreamt werden müssen, wenn Sie Snapshots verwenden. Wir haben einige verschiedene Indizes ausprobiert und festgestellt, dass in der Praxis einige zusätzliche Indizes zum Debuggen von realen Anwendungen in der Produktion erforderlich sind. Das sehen Sie wieder im Schema .
Andere produktionsinterne Metadaten waren bei produktionsbasierten Untersuchungen hilfreich. Zeitstempel gaben uns einen Einblick in die Reihenfolge, in der Ereignisse fortbestanden oder ausgelöst wurden. Dies gab uns Unterstützung bei einem besonders stark ereignisgesteuerten System, das eine große Anzahl von Ereignissen auslöste und uns Informationen über die Leistung von Dingen wie Netzwerken und die Systemverteilung über das Netzwerk gab.