When to denormalise: derived data and caches
Storing a value you could compute is a copy, and copies drift. When it is worth it, and how to let Postgres keep it right: a generated column inside the row, a materialised view across rows.
Checking your access…