I have a website which lists expenses filtered by year and allows for editing. Over the years, the expense entity evolved. Some properties were removed and some properties were added. If you go back and filter by a previous year, my website displays the expense by how it looked at the time.

In my database, all the different versions of the expense are stored under one table. If a property is removed, the associated column is kept but set to NULL for new entries. If a property is added, a new column is created and historical data is set to NULL.

The logic to determine which columns should be shown is currently in my presentation layer. Same thing for which columns can be edited.

Am I wrong to use the presentation layer for that? Should I split my expense entity by version in a domain layer so that the presentation layer only manipulates a single version?

Current design:

Infrastructure Layer:

ID, Amount, Vendor, Municipality, Purpose

Domain Layer:

ID, Amount, Vendor, Municipality, Purpose

Presentation Layer:

Year 2020:
ID, Amount, Vendor

Year 2021:
Id, Amount, Vendor, Municipality

Year 2022:
Id, Amount, Municipality, Purpose


Version the data.

How you store the object, relational db, one table, many tables, no-sql, whatever doesn’t matter so much as whether you store the version of the object with that data.

For example, in your current scheme you cant tell the difference between a valid 2020 expense and an invalid 2022 expense with missing vendor and purpose.

You will also doubtless get requirements where the version is important.

  • Upgrade all the 2020 expenses to 2022 by adding purpose=”old” and municipality= vendor
  • Report on all expenses by Vendor

Obviously if you version all your data ever, just in case you have backwards compatible requirements its going to be a pain. But versioning can be a life saver when you have data where you can’t translate from old to new versions or where the integrity of the originally entered information has to be preserved


Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *