-
Notifications
You must be signed in to change notification settings - Fork 29
Storage Structure
Even is built to be stored on SQL backends. The current structure is based on 3 tables: Events, ProjectionIndex and ProjectionCheckpoint.
This schema is given using the SQL Server format, but the same structure applies to any provider.
The main table where all events are stored. This is the only table that needs to be backed up or replicated.
create table Events (
GlobalSequence bigint not null primary key identity,
EventID uniqueidentifier not null unique,
StreamHash binary(20) not null,
StreamName varchar(200) not null,
EventType varchar(50) not null,
UtcTimestamp datetime not null,
Metadata varbinary(max),
Payload varbinary(max) not null,
PayloadFormat int not null
);
Details:
Field Name | Description |
---|---|
GlobalSequence | A global incrementing sequence that adds event ordering across streams. |
EventID | A guid that uniquely identifies each event. Is used mostly to prevent duplicated events. |
StreamHash | The SHA1 hash of the stream name. |
StreamName | The original stream name for informational purposes. May be truncated to fit if needed. |
EventType | The type/name of the event (usually the class name). |
UtcTimestamp | The timestamp in UTC for when the event was generated. |
Metadata | Additional metadata saved with the event. Usually contains the original CLR type name of the event to help deserialization. |
Payload | The actual event data (usually BSON serialized). |
PayloadFormat | A value indicating the format of the binary data in the Payload field. This is not used by currently, but may be used to implement encrypted payload. |
This table is maintained as an optimization for projections. Once projections match an event from the Events
table, the references are kept here.
This way, if a projection needs to be rebuilt, Even can look here and load only events that were already matched.
This table can be truncated at any time, it's contents will be rebuilt when Even starts.
create table ProjectionIndex (
ProjectionStreamHash binary(20) not null,
ProjectionStreamSequence int not null,
GlobalSequence bigint not null,
primary key (ProjectionStreamHash, ProjectionStreamSequence)
);
Details:
Field Name | Description |
---|---|
ProjectionStreamHash | The SHA1 hash of the stream. |
ProjectionStreamSequence | The sequence of the event in the projection. |
GlobalSequence | The sequence of the event in the global stream. |
This table is maintained as an optimization for projections. Every once in a while, projections will store here the last global sequence it saw, so if the application restarts, it doesn't need to recheck all events.
While projections already use the index to skip reloading unrequired events, the index only stores the events that match the projecton. If there are say 1000 events, and the last event matched in a projection was event 50, Even would still need to load events 51 through 1000 to make sure nothing was missed. The checkpoint stores the last event the projection saw, so restarts avoid reloading events unecessarily.
create table ProjectionCheckpoint (
ProjectionStreamHash binary(20) not null primary key,
LastGlobalSequence bigint not null
);
Details:
Field Name | Description |
---|---|
ProjectionStreamHash | The SHA1 hash of the stream. |
LastGlobalSequence | The last global sequence the projection saw. |