The basic idea of event sourcing is that instead of directly mutating a CRUD table, we generate Events into some kind of log, stream or event store and then as a consequence of those Events, we can change state somewhere, like in a CRUD table. The state always has to be derived directly from the events so that in can be recalculated at any point. (View Highlight)
Command Query Responsibility Segregation (CQRS) is just a fancy way of saying that your reads and writes go to different places. Without CQRS, reads would just read the event stream. However, with CQRS, writes go to the event store and reads go to a projection (state) table that is maintained from the event stream/log. (View Highlight)
In a temporal database, we store data in relation to time. For example, in our Orders table we can have a timestamp for when the Order arrived. And perhaps we use one of the methods described above to store transitions in the Order’s state with a timestamp so we know when changes happened to it. However, time and history have more than one dimension.
Valid time is the time period during which a fact is true in the real world.
“Where did Joe live in 1992?”
“When did the customer make the Order?”
Transaction time is the time at which a fact was recorded in the database.
“In 1992, where did the database believe Joe lived?”
“When did we write the Order to the database?”
Decision time is the time at which the decision was made about the fact.
“When did we learn about Joe’s home town of 1992?”
“When were we aware that an Order needs to be written to the database?” (View Highlight)
Note: So important! Have felt this but didn’t have the words
This might all seem like splitting hairs, but consider the following, rather common financial audit situation that requires a bitemporal (valid time + transaction time) modelling:
“Please report your sales from January 2016 from the system now, including all fixes to the data made since”
“Please report your sales from January 2016, as it was originally reported in February 1st, 2016” (so not including data fixes between then and now)
If Joe decides to use some kind of immutable event based system like SCD type2 or type4 tables or event sourcing, he will bump into a problem. If the data is immutable, how can you fix mistakes in the past that are already in the database? Bitemporal modelling solves this problem as you can declare in your events, rows or snapshots a valid time for when the information holds true and transactional time for when the information was written to the database. Now you can write to the past by appending new events/rows/snapshots with a valid time range that reaches to the past and transaction time of now(). You can have the immutable cake and eat it too. (View Highlight)
Note: This is a reporting problem we have every month