Como posso facilmente manter registros em um banco de dados ligados entre si?

StackOverflow https://stackoverflow.com/questions/1409206

  •  05-07-2019
  •  | 
  •  

Pergunta

Eu tenho um requisito que eu acredito que deve ocorrer com muita freqüência em todo o mundo. Eu tenho dois registos que estão ligados entre si e sempre que uma alteração é feita para eles um novo par de registros deve ser criado e manter o mesmo link.

A exigência de que estou trabalhando tem a ver com a indústria de seguros, que me obriga a desativar a atual política de seguros e re-ativá-los em uma nova linha, a fim de mostrar o histórico das alterações feitas às apólices de seguro. Quando eles são re-criados, eles ainda precisam ser ligados entre si.

Um exemplo de como este processo se destina ao trabalho a partir da visão de linhas em um banco de dados:

Seguro Id, Tipo Seguros, Seguro Mestre Id, Estado

1, Seguros Auto, null, Ativo

2, tela de vento Seguros, 1, Ativo

Note no exemplo acima como a ligação entre estas políticas é denotada pelo Insurance Mestre Id da segunda linha apontando o Id Seguro da primeira linha.

No código que estou escrevendo eu estou processando cada uma das políticas um de cada vez para que após o primeiro passo eu tenho a seguinte:

1, Seguros Auto, null, Inativo

2, tela de vento Seguros, 1, Ativo

3, Seguro Auto, null, Ativo

Quando eu processar a segunda política recebo a seguinte:

1, Seguros Auto, null, Inativo

2, Vento Tela Seguros, 1, Inativo

3, Seguro Auto, null, Ativo

4, Vento Tela Seguros, 1 , o Active // ??precisa ser 3 não 1

Você notará que quando eu criar o novo Seguro janela que desde que nós copiar a linha antiga vamos acabar com o apontamento de seguros mestre de identificação para a linha inativa.

A fim de contornar este problema, tenho de manter o controle do id seguro mestre da política anterior que foi processado, o que levou ao seguinte código:

int masterInsuranceId = -1;
foreach(Policy policy in policyList)
{
    //copy the old policy so the new policy has 
    //the same details as the old one
    Policy newPolicy = policyManager.Copy(policy);

    //if the new policy is not the master insurance store 
    //the master its new master insuance
    if(newPolicy.MasterInsuranceId.HasValue)
    {
       newPolicy.MasterInsuranceId = masterInsuranceId; 
    }

    //save the details of the new policy
    policyManager.SavePolicy(newPolicy);

    //record the master id so we can update the master id 
    //reference on the next policy
    if(newPolicy.MasterInsuranceId == null)
    {
        masterInsuranceId = newPolicy.Id;
    }
    else
    {
        masterInsuranceId = -1;
    }

    //inactivate the current policy
    policy.Status = Inactive;
    policyManager.UpdatePolicy(policy);

}

Alguém sabe como isso pode ser simplificado? Qual é a melhor maneira de garantir dois registros permanecerão ligados uns aos outros até mesmo como um histórico das alterações é registrada para cada alteração feita no registro?

Foi útil?

Solução 3

Obrigado a todos que tenha fornecido respostas. Infelizmente, devido às condições no trabalho eu sou incapaz de implementar mudanças de banco de dados e estou preso tentando fazer devido com uma solução de codificação.

Depois de passar algum tempo no fim de semana sobre este problema Eu tenho chegar a uma solução que eu acredito que simplifica o código um pouco, mesmo que ainda está longe de ser perfeito.

Eu extraí a funcionalidade para fora em um novo método e passar na política mestre que eu quero que a nova política ligada a.

Policy Convert(Policy policy, Policy masterPolicy)
{
    Policy newPolicy = policyManager.Copy(policy);

    //link the policy to it's master policy
    if(masterPolicy != null)
    {
        newPolicy.MasterPolicyId = masterPolicy.Id;
    }

    SavePolicy(newPolicy);

    //inactivate the current policy
    policy.Status = Inactive;
    policyManager.UpdatePolicy(policy);

    return newPolicy;
}

Isto permite-me para fazer um loop, em seguida, através de todas as políticas e passar na política que precisa ser ligada enquanto as políticas são classificadas na ordem correta ... que no meu caso é de data de início e, em seguida, pela política de mestre id.

Policy newPolicy = null;
foreach(Policy policy in policyList)
{
    Policy masterPolicy = policy.MasterPolicyId.HasValue ? newPolicy : null;
    newPolicy = Convert(policy, masterPolicy);   

}

Quando tudo estiver dito e feito, não é tudo o que muito menos código, mas eu acredito que é muito mais compreensível e permite que políticas individuais a ser convertido.

Outras dicas

Que tipo de esquema de banco de dados você está usando? Normalmente, este é onde o relacionamento deve ser armazenado e eu acho que isso deve ser hanlded no processamento de dados nível em vez de código.

Aqui está uma recomendação muito simplificada

seguros (, nome, descrição)

insurance_item (, , nome, descrição)

insurance_item_details (, , when_changed)

insurance__policy tem um 1 para muitos relação com insurance_item. Um insurance__item tem uma relação um para muitos com insurance_item_details. Cada linha insurance__item__details representa uma mudança na política.

Desta forma, a SQL pode rapidamente recuperar rapidamente os últimos dois itens

SELECT FROM insurance_item_details, insurance_item, insurance where
             insurance_item_details.item_id = insurance_item.item_id
             AND insurance_item.insurance_id = insurance.insurance_id
             ORDER BY when_changed
             LIMIT 1

Ou você ainda pode recuperar a história.

(O SQL não foi julgado)

Assim, a idéia é que você faz insurance_item não duplicado - você tem uma outra tabela para armazenar os elementos que seriam mudadas, e tapa um timestamp com ele declara que a mudança como um relacionamento.

Eu não sou um guru SQL (unfortnately), mas tudo o que você precisa fazer é inserir na tabela de insurance_item_details, em vez de fazer cópias. Do jeito que parece, fazer cópias, como no seu exemplo original parece violar 2NF, eu acho.

Se você tivesse um projeto do código ruim e você precisava fazer uma mudança que você refatorar? Então por que você não considerar refatoração um projeto de banco de dados ruim? Isso é algo que é mais ealisy tratado no banco de dados através de um bom design.

Se você estiver trabalhando no setor de seguros, que é intensiva de dados e você não é forte em habilidades de design de banco de dados e de consulta, eu sugiro que você faça disso uma prioridade para sê-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top