Comment conserver facilement des enregistrements dans une base de données liée?

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

  •  05-07-2019
  •  | 
  •  

Question

J'ai une exigence qui, à mon avis, doit être très fréquente dans le monde entier. J'ai deux enregistrements qui sont liés ensemble et chaque fois qu'une modification leur est apportée, une nouvelle paire d'enregistrements doit être créée et conserver le même lien.

L'exigence sur laquelle je travaille concerne le secteur des assurances, ce qui m'oblige à désactiver les polices d'assurance actuelles et à les réactiver dans une nouvelle ligne afin de montrer l'historique des modifications apportées aux polices d'assurance. Lorsqu'ils sont recréés, ils doivent encore être liés.

Voici un exemple de la manière dont ce processus est conçu pour afficher des lignes dans une base de données:

Identifiant d'assurance, type d'assurance, identifiant principal d'assurance, statut

1, assurance auto, null, actif

2, Assurance pare-vent, 1, actif

Notez ci-dessus comment le lien entre ces polices est désigné par l'identifiant d'assurance principal de la deuxième ligne qui pointe l'identifiant d'assurance de la première ligne.

Dans le code que j'écris, je traite chacune des stratégies une par une. Après la première étape, j'ai les éléments suivants:

1, Assurance auto, NULL, Inactif

2, Assurance pare-vent, 1, actif

3, Assurance auto, NULL, Actif

Lorsque je traite la deuxième stratégie, j'obtiens les informations suivantes:

1, Assurance auto, Null, Inactif

2, Assurance pare-vent, 1, inactif

3, assurance auto, null, actif

4, assurance écran anti-vent, 1 , actif // doit être 3 et non 1

Vous remarquerez que lors de la création de la nouvelle assurance de fenêtre, nous recoupons la vieille ligne avec l'assurance Master Id qui pointe vers la ligne inactive.

Afin de résoudre ce problème, je dois garder une trace de l'identifiant principal de l'assurance du contrat précédent traité, qui a conduit au code suivant:

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);

}

Est-ce que quelqu'un sait comment cela peut être simplifié? Quel est le meilleur moyen de s’assurer que deux enregistrements resteront liés, même si un historique des modifications est enregistré pour chaque modification apportée à l’enregistrement?

Était-ce utile?

La solution 3

Merci à tous ceux qui ont fourni des réponses. Malheureusement, en raison de conditions de travail, je ne parviens pas à mettre en œuvre les modifications de base de données et je ne parviens pas à résoudre le problème avec une solution de codage.

Après avoir passé quelque temps sur ce problème ce week-end, j'ai proposé une solution qui, je pense, simplifie un peu le code, même s'il est encore loin d'être parfait.

J'ai extrait la fonctionnalité dans une nouvelle méthode et transmis la stratégie principale à laquelle la nouvelle stratégie doit être liée.

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;
}

Cela me permet de parcourir toutes les stratégies et de transmettre la stratégie à lier tant que les stratégies sont triées dans le bon ordre ... ce qui dans mon cas correspond à la date de début, puis à la stratégie principale. id.

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

}

Quand tout est dit et fait, ce n’est pas moins du code, mais je pense que c’est beaucoup plus compréhensible et que cela permet de convertir des stratégies individuelles.

Autres conseils

Quel type de schéma de base de données utilisez-vous? Habituellement, c’est à cet endroit que les relations devraient être stockées et je pense que cela devrait être modifié au niveau du traitement des données plutôt que du code.

Voici une recommandation très simplifiée

assurance (< insurance_id > ;, nom, description)

insurance_item (< item_id > ;, < insurance_id > ;, nom, description)

insurance_item_details (< item_id > ;, < policy_id > ;, quand_changé)

insurance__policy a une relation un à plusieurs avec insurance_item. Un élément insurance__ entretient une relation un à plusieurs avec insurance_item_details. Chaque ligne du détail assurance__item__détails représente un changement de police.

De cette façon, un SQL peut récupérer rapidement les deux derniers éléments

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 vous pouvez même récupérer l'historique.

(Le code SQL n'a pas été essayé)

Donc, l’idée est de ne pas dupliquer insurance_item - vous avez une autre table pour stocker les éléments qui seraient modifiés, et claquez un horodatage avec celui-ci pour représenter ce changement en tant que relation.

Je ne suis pas un gourou de SQL (malheureusement), mais tout ce que vous avez à faire est d'insérer dans la table insurance_item_details au lieu de faire des copies. D'après ce que cela donne, faire des copies comme dans votre exemple original semble violer 2NF, je pense.

SI vous aviez une mauvaise conception de code et que vous deviez apporter une modification, refacteriez-vous? Alors pourquoi ne pas envisager de refactoriser une conception de base de données incorrecte? C’est quelque chose qui est plus vraisemblablement traité dans la base de données grâce à une bonne conception.

Si vous travaillez dans le secteur de l’assurance en utilisant beaucoup de données et que vous n’êtes pas très fort en conception de bases de données et en compétences en matière d’interrogation, je vous conseillerais de donner la priorité à cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top