To add Charles's answer , I would use the Entity-Attribute-Value model instead of creating another history table for every other table in your database.
Essentially, you would create one History table as follows:
Create Table History { tableId varChar(64) Not Null, recordId varChar(64) Not Null, changedAttribute varChar(64) Not Null, newValue varChar(64) Not Null, effectiveUtc DateTime Not Null, Primary Key (tableId , recordId , changedAttribute, effectiveUtc) }
You will then create a History record each time you create or modify data in one of your tables.
Following your example, when you add “Kyle” to the Employee table, you create two records (one for each attribute without an identifier), and then create a new record each time the property changes:
History +==========+==========+==================+==========+==============+ | tableId | recordId | changedAttribute | newValue | effectiveUtc | | Employee | 1 | Name | Kyle | N | | Employee | 1 | Property | 30 | N | | Employee | 1 | Property | 50 | N+1 | | Employee | 1 | Property | 70 | N+2 |
Alternatively, as suggested by a_horse_with_no_name , if you do not want to save a new History record for each field change, you can save the grouped changes (such as changing the Name to "Kyle" and Property to 30 in the same update) as a single record , In this case, you will need to express a collection of changes in JSON or another format of BLOB objects. This will combine the changedAttribute and newValue into one ( changedValues ). For example:
History +==========+==========+================================+==============+ | tableId | recordId | changedValues | effectiveUtc | | Employee | 1 | { Name: 'Kyle', Property: 30 } | N |
This may be more complicated than creating a history table for every other table in your database, but it has several advantages:
- adding new fields to tables in your database will not require adding these fields to another table
- fewer tables used
- It’s easier to relate updates to different tables over time.
One architectural advantage of this design is that you share the challenges of your application with your story / audit capabilities. This design will work just as well as a microservice using a relational database or even a NoSQL database that is separate from your application database.