Как мне легко хранить записи в базе данных, связанной вместе? - PullRequest
0 голосов
/ 11 сентября 2009

У меня есть требование, которое, по моему мнению, должно происходить очень часто по всему миру. У меня есть две записи, которые связаны друг с другом, и всякий раз, когда в них вносится изменение, создается новая пара записей и сохраняется та же ссылка.

Требование, над которым я работаю, касается страховой отрасли, которая требует от меня деактивировать текущие страховые полисы и повторно активировать их в новом ряду, чтобы показать историю изменений, внесенных в страховые полисы. Когда они воссозданы, их все равно нужно связать вместе.

Пример того, как этот процесс предназначен для работы с представлением строк в базе данных:

Идентификатор страховки, Тип страховки, Основной идентификатор страховки, Статус

1, Автострахование, ноль, Актив

2, Страхование ветрового стекла, 1, Актив

Обратите внимание на то, как выше указана связь между этими полисами с помощью основного идентификатора страхования второй строки, указывающего идентификатор страхования первой строки.

В коде, который я пишу, я обрабатываю каждую из политик по одному, поэтому после первого шага у меня появляется следующее:

1, Автострахование, ноль, Неактивно

2, Страхование ветрового стекла, 1, Актив

3, Автострахование, ноль, Актив

Когда я обрабатываю вторую политику, я получаю следующее:

1, автострахование, ноль, неактив

2, страхование ветрового стекла, 1, Неактивно

3, Автострахование, ноль, Актив

4, страхование ветрового стекла, 1 , Active // ​​должно быть 3, а не 1

Вы заметите, что когда я создаю новую страховку окна, поскольку мы копируем старую строку, мы получаем страховку Master Id, указывающую на неактивную строку.

Чтобы обойти это, я должен отслеживать основной страховой идентификатор предыдущего полиса, который был обработан, что привело к следующему коду:

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

}

Кто-нибудь знает, как это можно упростить? Как лучше всего обеспечить, чтобы две записи оставались связанными друг с другом, даже если история изменений записывается для каждого изменения, внесенного в запись?

Ответы [ 3 ]

2 голосов
/ 11 сентября 2009

Какую схему базы данных вы используете? Обычно это то место, где должны храниться отношения, и я думаю, что это должно осуществляться на уровне обработки данных, а не кода.

Вот очень упрощенная рекомендация

страховка (, название, описание)

insurance_item (, , имя, описание)

insurance_item_details (, , когда изменено)

insurance__policy имеет отношение 1 к многим с insurance_item. Элемент insurance__item имеет отношение один ко многим с insurance_item_details. Каждая строка в insurance__item__details представляет изменение в полисе.

Таким образом, SQL может быстро и быстро получить последние два элемента

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

Или вы можете даже извлечь историю.

(SQL не был опробован)

Таким образом, идея в том, что вы не дублируете insurance_item - у вас есть другая таблица для хранения элементов, которые будут изменены, и добавление временной метки, чтобы представить это изменение как отношение.

Я не гуру SQL (к сожалению), но все, что вам нужно сделать, это вставить в таблицу insurance_item_details вместо того, чтобы делать копии. На мой взгляд, создание копий, как в вашем оригинальном примере, нарушает 2NF.

0 голосов
/ 14 сентября 2009

Спасибо всем, кто предоставил ответы. К сожалению, из-за условий на работе я не могу внести изменения в базу данных, и я застрял, пытаясь сделать это с помощью решения для кодирования.

Потратив некоторое время на выходных на эту проблему, я нашел решение, которое, как мне кажется, немного упрощает код, хотя он еще далеко не идеален.

Я извлек функциональность в новый метод и передал основную политику, с которой я хочу связать новую политику.

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

Это позволяет мне затем циклически проходить через все политики и передавать политику, которая должна быть связана, если политики отсортированы в правильном порядке ... что в моем случае - по дате начала, а затем по основной политике ID.

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

}

Когда все сказано и сделано, это не так уж много кода, но я считаю, что он гораздо более понятен и позволяет конвертировать отдельные политики.

0 голосов
/ 11 сентября 2009

Если бы у вас был плохой дизайн кода, и вам нужно было внести изменения, вы бы сделали рефакторинг? Тогда почему бы вам не подумать о рефакторинге плохого дизайна базы данных? Это то, что более эффективно обрабатывается в базе данных благодаря хорошему дизайну.

Если вы работаете в страховой отрасли, которая интенсивно использует данные, и у вас недостаточно сильных навыков проектирования баз данных и запросов, я бы посоветовал вам сделать это приоритетом.

...