Event Sourcing: Underling Storage Engine Options

The emergence of NoSQL is an interesting movement. One of the key principles behind NoSQL is related to the simplicity of the data store. This is in contrast to a traditional RDBMS. The amount of code required to create a production-grade relational database is far from trivial. Of course, NoSQL goes far beyond this and pushes hard on CAP and the ability to scale out.

One of the beauties of event sourcing and specifically the event store is that it has relatively few, yet well-defined requirements that it puts on the underlying storage engine. One of these requirements is that the event store be transactional on a per-aggregate basis.

In my EventStore library found on GitHub, I created a relatively simple abstraction to represent an event store. One that could read and write a set of committed and uncommitted events, respectively. There are relatively few "if" statements as the code makes its way down through the various layers of abstraction to the underlying storage provider.

In the EventStore library, I have implemented a StorageAdapter that can talk to a relational database. In fact, I've created adapters that can talk to:

  1. Microsoft SQL Server 7 (or later)
    1. This particular adapter is capable of talking to SQL Server CE and even Microsoft Access 95.
  2. MySQL 4 (or later)
  3. SQLite 3 (or later)
  4. PostgreSQL 7 (or later)

The main reason I bring this up is to illustrate the relatively few requirements that the event store makes upon the underlying storage infrastructure. Furthermore, it becomes very, very easy to test an event store with a different storage engine adapter (e.g. Oracle, DB2, XML files, binary stream, etc.) because there are so few code paths to be exercised all the way down through the storage engine itself.

This is good news because there are a number of interesting storage engines that are worth investigating more fully such as MariaDB, Drizzle, XtraDB, Galera, MySQL Cluster, and others in the RDBMS crowd. One reason many have been hesitant to investigate these solutions more fully relates to potential bugs lurking deep in the codebase. But because we're only using the most basic of features from our storage engine, we avoid a significant number of issues that we might otherwise encounter when using a less-mature storage engine.

In the NoSQL crowd, the only thing that we require is optimistic concurrency which unfortunately eliminates some of the Dynamo clones.

Conclusion

Using event sourcing allows us to investigate alternative storage engines that we might have otherwise been hesitant to investigate.