What is the difference between a "root aggregate" and "aggregate" in an event store?
I'm having trouble accurately defining these even after hours of searching. My understanding is that an aggregate is a table of IDs that group together events (collection) within the store often with object representations which is why there can also be an aggregate type.
Additionally, I've seen aggregate tables with version numbers which I find confusing under the premise that they are essentially group/container/aggregate IDs representing a collection of events.
So we have agreed that you are trying to make event streams to DDD Aggregate Root and Aggregate patterns.
There is a common pattern that each aggregate has its own stream. It has the name and identity of the aggregate root, although the name part is not a requirement.
All operations on the whole aggregate are represented by events, which are then written to this stream.
So if you have an aggregate root MyNamespace.Order
, which has multiple child value objects or entities MyNamespace.OrderLine
, all operation on lines are done by accessing aggregate root methods and all events are written to one stream, so for the Order with id 123 it would be:
Stream: MyName
The concept of entities is not represented on the event store side since you cannot easily define relations between different streams to read events from multiple streams in order to recompose the aggregate. Therefore, all events are written and read in the aggregate root stream, which then becomes the stream for the whole aggregate.
One important rule about aggregates is that aggregate is also the consistency boundary. This basically means that all operations on an aggregate must be done in one transaction.
It is important to keep the event version to handle concurrency. When you read an aggregate from the event store, you get the latest event version too. After performing the operation, you write new events back, checking if the latest event version is still the same. If the last event version does not match, you throw the concurrency exception since someone has already changed the aggregate and wrote changes to the store before you did and you got a conflict.
Concerning "tables" I am not quite sure what you mean. Certainly, you can model your event store in tables and there are different strategies on doing this. More often then not you would really prefer using specialised event store, like this one.