Pergunta
Qual é a melhor prática para garantir que uma chave de uma tabela "Grand-Parent" ou "Bis Grand-Parent" seja mantida quando uma tabela "Child" ou "Grand-Child" é criada a partir de várias árvores de relacionamento.
Detalhes, já que essa pergunta provavelmente não faz sentido
Estou tentando construir um banco de dados para acompanhar o status de execução dos processos automatizados em execução em nosso ambiente.
Em geral temos um "Job" que aciona um ou mais "Executáveis" e esses "Executáveis" podem executar tarefas para um ou mais clientes. Teremos então 2 tabelas de registro, uma que rastreia quando um "Job" foi iniciado e outra que registrará o status de Sucesso x Falha de cada instância "ExecutableCustomer".
Um Esquema Simplificado Planejado está abaixo:
Quando corrigirmos o registro para o JobExecutableCustomerExecutionLog
, gostaria de garantir que o Job.ID
valor associado ao JobExecutionLog.ID
valor corresponda ao Job.ID
valor associado ao JobExecutableCustomer.ID
.
Normalmente eu lidaria com isso com um Foreign Key
mas uma vez que Job.ID
não é armazenado em JobExecutableCustomer
, JobExecutableCustomerExecutionLog
nem JobExecutionLog
. A relação é indireta.
Exemplo:
Tenho 2 empregos, "Enviar e-mail" e "Enviar mensagem de texto". "Enviar Email" inicia um único executável que pertence a 1 Cliente. "Enviar mensagem de texto" possui 2 executáveis (ambos executados para o mesmo cliente). Quero ter certeza de que, quando o registro for gravado JobExecutableCustomerExecutionLog
para "Enviar e-mail", o Job.ID
associado JobExecutableCustomerExecutionLog.JobExecutableCustomerID
e JobExecutableCustomerExecutionLog.JobExecutionLogID
(depois de percorrer os relacionamentos) realmente pertença a Job.ID
"Enviar e-mail" e não a "Enviar mensagem de texto".
Pelo que vejo tenho 2 opções:
- Empurre o valor de
Job.ID
todas as tabelas filhas e torne-o parte doForeign Key
- Ter outro processo (
Trigger
ouIndexed View
) garantir os relacionamentos para mim
Eu pessoalmente não gosto da ideia de empurrar o Job.ID
valor em todas as outras tabelas filhas, então estou inclinado a usar a Trigger
ou outra coisa para lidar com isso. Eu não sabia se essas eram minhas únicas duas opções ou se eu tenho a capacidade de configurar um "normal" Foreign Key
para percorrer os relacionamentos até o fim. Em algum tipo de Cascade
ou alguma outra coisa.
Por que não? A solução óbvia é tornar JobID a principal coluna de índice PK/clustered em todas as tabelas filhas. E garante um ótimo desempenho para acessar todas essas tabelas por JobID.
Geralmente sempre que você tem um "relacionamento de identificação" também conhecido como "tabela filho" também conhecido como "entidade fraca", a tabela filho deve usar uma chave primária composta cujas colunas principais também são a chave estrangeira para a tabela pai. Algo assim:
Um exemplo de como a integridade dos dados pode ser mantida usando o
FKs
. Modifiquei um pouco o modelo para permitir que um executável faça parte de mais de um trabalho. A suposição é que, quando um executável é executado, ele é executado para todos os clientes associados a esse executável. Seu ERD não mostra restrições, portanto, há algumas suposições envolvidas.Uma suposição é que as tarefas gravam em
log_
tabelas, portanto, espera-se alguma redundância: comoEXE
emlog_job
; aindaFKs
evitar anomalias.Observação: