Skip to content

Latest commit

 

History

History
49 lines (35 loc) · 10.7 KB

DATABASE_SCHEMA.md

File metadata and controls

49 lines (35 loc) · 10.7 KB

DynamoDB table schema used by EventStore

  • Journal
  • Snapshot

The key design assumption for both tables is that writes are distributed to the greatest extent possible within the logical shard.

Journal table

The table used to store events that have occurred in an aggregate. In principle, this event is used to replay (replay) the aggregate state.

key name description example remarks
pkey Partition key(${aggregate-type-name}-hash($aid) % logical-shard-size) user-account-1
skey Sort Key(${aggregate type name}-${aid.value}-${seq_nr}) user-account-01H42K4ABWQ5V2XQEP3A48VE0Z-12345
aid Aggregate ID user-account-01H42K4ABWQ5V2XQEP3A48VE0Z
ser_nr Sequence Number(origin=1) 12345
payload Event Payload {"type":"Created","id":"01H42KBHCW1BZG504J4ZXKA2F2","aggregate_id":{"value":"01890535-c59c-72d5-08a8-dcea316374c8"},"seq_nr":1,"name":"test","members":{"members_ids_by_user_account_id":{"01H42KBHCWBDTZYQ7P78T8BTWX":"01H42KBHCWA8NE32M49YH544H1"},"members":{"01H42KBHCWA8NE32M49YH544H1":{"id":"01H42KBHCWA8NE32M49YH544H1","user_account_id":{"value":"01890535-c59c-5b75-ff5c-f63a3485eb9d"},"role":"Admin"}}},"occurred_at":"2023-06-29T03:32:37.404481Z"}
occurred_at Occurred DateTime of the Event 2023-06-29T03:32:37.404481Z

GSI is applied to aid and seq_nr, and this index is used during replay.

Snapshot table

This table is used to store aggregate state and to speed up replay of aggregates. It may not represent the latest aggregation state because events are saved even after the snapshot is saved.

column name description example remarks
pkey Partition key(${aggregate-type-name}-hash($aid) % logical-shard-size) user-account-1
skey Sort Key(${aggregate type name}-${aid.value}-${seq_nr}), The latest snapshot is read/written as seq_nr=0. user-account-01H42K4ABWQ5V2XQEP3A48VE0Z-12345
payload State of Aggregate {"id":{"value":"0189053a-d0b4-8f9b-4fb6-db91f72ccf16"},"name":"test","members":{"members_ids_by_user_account_id":{"01H42KNM5MBVRBZTADAZ9ETSPZ":"01H42KNM5M2QEW700VCW4J2KYE"},"members":{"01H42KNM5M2QEW700VCW4J2KYE":{"id":"01H42KNM5M2QEW700VCW4J2KYE","user_account_id":{"value":"0189053a-d0b4-5ef0-bfe9-4d57d2ed66df"},"role":"Admin"}}},"messages":[],"seq_nr_counter":1,"version":1}
aid Aggregate ID user-account-01H42K4ABWQ5V2XQEP3A48VE0Z
ser_nr Sequence Number(origin=1) 12345
ttl TTL for deletion(seconds) 1624980000
version Version for optimistic lock(origin=1) 1
  • When the snapshot redundancy feature is disabled, only a snapshot is stored at skey=0. When enabled, two snapshots are stored at skey=aggregate.seq_nr() in addition to skey=0. Each time a snapshot is saved, skey=aggregate.seq_nr() snapshot will be increased, but you can specify an upper limit for the snapshot (default is 1). If the upper limit is exceeded, the older snapshots will be deleted first. By default, the deletion is client-initiated; you can also use TTL to let DynamoDB itself do the deletion.
  • GSI is applied to aid and seq_nr, and this index is used during replay.

Writing events and snapshots

  1. When the command is accepted by aggregate, an event with the latest seq_nr is generated.
  2. The generated events are written to the journal table. However, this write is always done in the same transaction as the snapshot table and under version matching conditions. Except for the first event, updating the payload of snapshot is optional.

Replaying an aggregate with events and snapshots

  1. Specify the ID of the aggregate and take a snapshot.
  2. Read the events from the journal table after the ID of the retrieved aggregate and the sequence number of the snapshot.
  3. Apply the read events to the snapshot to obtain the latest aggregate state.