كيف يمكنني بسهولة الاحتفاظ بالسجلات في قاعدة بيانات مرتبطة ببعضها البعض؟

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

  •  05-07-2019
  •  | 
  •  

سؤال

لدي مطلب أعتقد أنه يجب أن يحدث بشكل متكرر حول العالم.لدي سجلين مرتبطين معًا وكلما تم إجراء تغيير عليهما، سيتم إنشاء زوج جديد من السجلات والاحتفاظ بنفس الارتباط.

المطلب الذي أعمل عليه يتعلق بصناعة التأمين والذي يتطلب مني إلغاء تفعيل وثائق التأمين الحالية وإعادة تفعيلها في صف جديد لإظهار تاريخ التغييرات التي تم إجراؤها على وثائق التأمين.عندما يتم إعادة إنشائها، فإنها لا تزال بحاجة إلى ربطها معًا.

مثال على كيفية عمل هذه العملية من عرض الصفوف في قاعدة البيانات:

معرف التأمين، نوع التأمين، معرف التأمين الرئيسي، الحالة

1، التأمين على السيارات، لاغية، نشطة

2، تأمين ضد الرياح، 1، نشط

لاحظ ما ورد أعلاه كيف يتم الإشارة إلى الارتباط بين هذه السياسات من خلال معرف التأمين الرئيسي للصف الثاني الذي يشير إلى معرف التأمين للصف الأول.

في الكود الذي أكتبه، أقوم بمعالجة كل سياسة واحدة تلو الأخرى، لذلك بعد الخطوة الأولى لدي ما يلي:

1, تأمين السيارات, لاغية, غير نشط

2، تأمين ضد الرياح، 1، نشط

3, تأمين السيارات, لاغية, نشيط

عندما أقوم بمعالجة السياسة الثانية أحصل على ما يلي:

1، التأمين على السيارات، لاغية، غير نشط

2، التأمين ضد الرياح، 1، غير نشط

3، التأمين على السيارات، لاغية، نشطة

4، تأمين شاشة الرياح، 1, ، نشط // يجب أن يكون 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

شكرا لكل من قدم الإجابات.لسوء الحظ، نظرًا لظروف العمل، لا أستطيع تنفيذ تغييرات قاعدة البيانات وأنا عالق في محاولة الالتزام بحل الترميز.

بعد قضاء بعض الوقت خلال عطلة نهاية الأسبوع في حل هذه المشكلة، توصلت إلى حل أعتقد أنه يبسط الكود قليلاً على الرغم من أنه لا يزال بعيدًا عن الكمال.

لقد استخرجت الوظيفة إلى طريقة جديدة وقمت بتمرير السياسة الرئيسية التي أريد ربط السياسة الجديدة بها.

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

يتيح لي ذلك تكرار جميع السياسات وتمرير السياسة التي يجب ربطها طالما تم فرز السياسات بالترتيب الصحيح... وهو في حالتي حسب تاريخ البدء ثم حسب معرف السياسة الرئيسية.

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

}

بعد كل ما قيل وفعل، لا يقتصر الأمر على التعليمات البرمجية ولكن أعتقد أنها أكثر قابلية للفهم وتسمح بتحويل السياسات الفردية.

نصائح أخرى

ما نوع مخطط قاعدة البيانات الذي تستخدمه؟عادة، هذا هو المكان الذي يجب أن يتم فيه تخزين العلاقة وأعتقد أنه يجب التعامل معها على مستوى معالجة البيانات بدلاً من التعليمات البرمجية.

إليك توصية مبسطة للغاية

التأمين (<insurance_id>، الاسم، الوصف)

Insurance_item(< item_id >، <insurance_id >، الاسم، الوصف)

Insurance_item_details(< item_id >, <policy_id >, When_changed)

لدى Insurance__policy علاقة 1 إلى العديد مع Insurance_item.يحتوي عنصر_التأمين على علاقة فردية مع تفاصيل_عنصر_التأمين.يمثل كل صف في 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، على ما أعتقد.

إذا كان لديك تصميم برمجي سيئ وكنت بحاجة إلى إجراء تغيير، فهل ستعيد البناء؟إذن لماذا لا تفكر في إعادة هيكلة تصميم قاعدة بيانات سيئة؟وهذا أمر يسهل التعامل معه في قاعدة البيانات من خلال التصميم الجيد.

إذا كنت تعمل في مجال التأمين الذي يعتمد على البيانات بشكل مكثف، ولم تكن قويًا في تصميم قواعد البيانات ومهارات الاستعلام، فإنني أقترح عليك أن تجعل ذلك من أولوياتك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top