Considerando essas duas tabelas no 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 |
+----+--------------+-------------+------+
- Dado que
report_id_fk
é uma chave estrangeira nareport_years
tabela, não haveria uma maneira deCASCADE
atualizar oreport_name
com base emreport_id_fk
? - Eles teriam que ser chaves estrangeiras separadas?
report_name
nem deveria estar nareport_years
tabela em primeiro lugar, pois é redundante e deve ser consultado com umJOIN
toreport
?- É possível ter uma restrição de chave estrangeira de vários campos tal que
report_name
eyear
seria necessária para umCASCADE
?
Por exemplo:
# 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 |
+----+-----------+----------------+---------+---------+
- Se eu quisesse alterar o
report_name
foryear = 2020
inreport
, ele fariaCASCADE
ereport_details
atualizaria oreport_name_fk
com base noreport_name_fk
andyear_fk
? - Ou (voltando à pergunta 1), posso configurar um
CASCADE
que seja atualizadoreport_name_fk
eyear_fk
emreport_details
?
Eu posso ver como fazer isso com um manual UPDATE
, mas vendo se é possível com CASCADE
. Ou, como eu acho, isso é redundante, deve ser evitado e se você precisa saber report_name
e year
para um relatório em report_details
, você deve apenas escrever uma consulta JOIN
nele.
Você pode resolver isso com uma chave estrangeira de duas colunas e atualização em cascata, mas isso requer uma restrição exclusiva de duas colunas redundantes em
report
, o que prejudicará o desempenho de DML e usará espaço de armazenamento extra.A solução adequada é remover a coluna redundante do
report_years
. Esse conceito de remover redundância de um modelo de dados para melhorar a consistência é tão importante que existe um nome para ele: normalização.