Question

Considering these two tables in PosgtreSQL:

# report
+----+-------------+--------------------+
| id | report_name | report_description |
+----+-------------+--------------------+
| 1  | RPT         | ABCDEFGH           |
| 2  | TST         | LMNOPQRS           |
+----+-------------+--------------------+

# report_years
+----+--------------+-------------+------+
| id | report_id_fk | report_name | year |
+----+--------------+-------------+------+
| 11 | 1            | RPT         | 2019 |
| 12 | 1            | RPT         | 2020 |
| 13 | 2            | TST         | 2019 |
+----+--------------+-------------+------+
  1. Given that report_id_fk is a foreign key in the report_years table, there wouldn't be a way to CASCADE and update the report_name based on report_id_fk?
  2. They would have to be separate foreign keys?
  3. report_name shouldn't even be in the report_years table in the first place since it is redundant and should just be queried over with a JOIN to report?
  4. Is it possible to have a multifield foreign key constraint such that report_name and year would be required for a CASCADE?

For example:

# report
+----+-------------+------+
| id | report_name | year |
+----+-------------+------+
| 1  | RPT         | 2018 |
| 2  | RPT         | 2019 |
| 3  | RPT         | 2020 |
+----+-------------+------+

# report_details
+----+-----------+----------------+---------+---------+
| id | report_id | report_name_fk | year_fk | details |
+----+-----------+----------------+---------+---------+
| 11 | 1         | RPT            | 2018    | ABC     |
| 12 | 2         | RPT            | 2019    | DEF     |
| 13 | 3         | RPT            | 2020    | GHI     |
+----+-----------+----------------+---------+---------+
  1. If I wanted to change the report_name for year = 2020 in report, it would CASCADE to report_details and update the report_name_fk based on the report_name_fk and year_fk?
  2. Or (back to question 1), can I setup a CASCADE that would updated report_name_fk and year_fk in report_details?

I can see how to do this with a manual UPDATE, but seeing if it is possible with CASCADE. Or, like I think, this is redundant, should be avoided and if you need to know report_name and year for a report in report_details, you should just write a query an JOIN it.

Was it helpful?

Solution

You could solve this with a two-column foreign key and cascading update, but that requires a redundant two-column unique constraint on report, which will harm DML performance and use extra storage space.

The proper solution is to remove the redundant column from report_years. This concept of removing redundancy from a data model to improve consistency is so important that there is a name for it: normalization.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top