سؤال

عند إعداد المفاتيح الخارجية في SQL Server، تحت أي ظروف يجب أن يكون لديك سلسلة متتالية عند الحذف أو التحديث، وما هو السبب وراء ذلك؟

ربما ينطبق هذا على قواعد البيانات الأخرى أيضًا.

أنا أبحث أكثر من أي شيء آخر عن أمثلة ملموسة لكل سيناريو، ويفضل أن يكون ذلك من شخص استخدمها بنجاح.

هل كانت مفيدة؟

المحلول

ملخص ما رأيته حتى الآن:

  • بعض الناس لا يحبون المتتالية على الإطلاق.

حذف تتالي

  • قد يكون الحذف المتتالي منطقيًا عندما تتضمن دلالات العلاقة حصريًا "هو جزء من" وصف.على سبيل المثال، يعد سجل OrderLine جزءًا من الترتيب الأصلي الخاص به، ولن تتم مشاركة OrderLines مطلقًا بين أوامر متعددة.إذا اختفى الطلب، فيجب أن يختفي خط الطلب أيضًا، وسيكون السطر بدون أمر مشكلة.
  • المثال المتعارف عليه لحذف Cascade هو SomeObject وSomeObjectItems، حيث ليس من المنطقي أن يوجد سجل العناصر بدون سجل رئيسي مطابق.
  • يجب لا استخدم Cascade Remove إذا كنت تحتفظ بالمحفوظات أو تستخدم "الحذف الناعم/المنطقي" حيث تقوم فقط بتعيين عمود البت المحذوف على 1/صحيح.

تحديث تتالي

  • قد يكون التحديث المتتالي منطقيًا عند استخدام مفتاح حقيقي بدلاً من مفتاح بديل (عمود الهوية/الزيادة التلقائية) عبر الجداول.
  • المثال الأساسي لـ Cascade Update هو عندما يكون لديك مفتاح خارجي قابل للتغيير، مثل اسم المستخدم الذي يمكن تغييره.
  • يجب لا استخدم Cascade Update مع المفاتيح التي تمثل أعمدة الهوية/الزيادة التلقائية.
  • من الأفضل استخدام Cascade Update مع قيد فريد.

متى تستخدم المتتالية

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

نصائح أخرى

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

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

مثال خوان مانويل هو المثال الأساسي، إذا كنت تستخدم التعليمات البرمجية، فهناك العديد من الفرص لترك DocumentItems زائفة في قاعدة البيانات التي ستأتي وتعضك.

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

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

لا أستخدم عمليات الحذف المتتالية مطلقًا.

إذا أردت إزالة شيء ما من قاعدة البيانات، فأنا أريد أن أخبر قاعدة البيانات صراحةً بما أريد إزالته.

بالطبع هي وظيفة متاحة في قاعدة البيانات وقد تكون هناك أوقات يكون من المناسب استخدامها، على سبيل المثال، إذا كان لديك جدول "order" وجدول "orderItem"، فقد ترغب في مسح العناصر عند حذف عنصر طلب.

يعجبني الوضوح الذي أحصل عليه من القيام بذلك في التعليمات البرمجية (أو الإجراء المخزن) بدلاً من حدوث "سحر".

لنفس السبب أنا لست من محبي المحفزات أيضًا.

ما يجب ملاحظته هو أنه إذا قمت بحذف "الطلب"، فستحصل على تقرير "صف واحد متأثر" مرة أخرى حتى إذا أدى الحذف المتتالي إلى إزالة 50 "طلبًا".

أنا أعمل كثيرًا مع عمليات الحذف المتتالية.

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

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

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

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

بشكل عام، أتجنب عمليات الحذف الحقيقية تمامًا وأستخدم عمليات الحذف المنطقية (على سبيل المثال.وجود عمود بت يسمى isDeleted والذي يتم ضبطه على true) بدلاً من ذلك.

أحد الأمثلة هو عندما يكون لديك تبعيات بين الكيانات ...أي:المستند -> DocumentItems (عند حذف المستند، لا يوجد سبب لوجود DocumentItems)

استخدم الحذف المتتالي حيث تريد إزالة السجل الذي يحتوي على FK إذا تمت إزالة سجل PK المرجعي الخاص به.بمعنى آخر، حيث يكون السجل بلا معنى بدون السجل المرجعي.

أجد أن الحذف المتتالي مفيد لضمان إزالة المراجع الميتة افتراضيًا بدلاً من التسبب في استثناءات فارغة.

تشغيل الحذف المتتالي:

عندما تريد الصفوف الموجودة في الجدول الفرعي المراد حذفها لو يتم حذف الصف المقابل في الجدول الأصل

لو على حذف تتالي إذا لم يتم استخدامه، فسيظهر خطأ لـ التكامل المرجعي.

تشغيل سلسلة التحديثات:

عندما تريد التغيير في المفتاح الأساسي ليتم تحديثها في مفتاح غريب

أحد أسباب إجراء الحذف المتتالي (بدلاً من القيام بذلك في الكود) هو تحسين الأداء.

حالة 1:مع حذف تتالي

 DELETE FROM table WHERE SomeDate < 7 years ago;

الحالة 2:دون حذف تتالي

 FOR EACH R IN (SELECT FROM table WHERE SomeDate < 7 years ago) LOOP
   DELETE FROM ChildTable WHERE tableId = R.tableId;
   DELETE FROM table WHERE tableId = R.tableid;
   /* More child tables here */
 NEXT

ثانيًا، عند إضافة جدول فرعي إضافي مع حذف متتالي، يستمر الكود الموجود في الحالة 1 في العمل.

أود فقط أن أضع سلسلة حيث تكون دلالات العلاقة "جزءًا منها".وإلا فإن بعض الأحمق سوف يحذف نصف قاعدة البيانات الخاصة بك عندما تفعل:

DELETE FROM CURRENCY WHERE CurrencyCode = 'USD'

لقد سمعت عن مسؤولي قواعد البيانات و/أو "سياسة الشركة" التي تحظر استخدام "On Remove Cascade" (وغيرها) فقط بسبب التجارب السيئة في الماضي.في إحدى الحالات، كتب رجل ثلاثة مشغلات انتهت بالاتصال ببعضها البعض.أدت ثلاثة أيام للتعافي إلى فرض حظر كامل على المشغلات، كل ذلك بسبب تصرفات أحد الأشخاص.

بالطبع في بعض الأحيان تكون هناك حاجة إلى مشغلات بدلاً من "عند الحذف المتتالي"، كما هو الحال عندما يلزم الحفاظ على بعض بيانات الطفل.ولكن في حالات أخرى، يكون من الصحيح تمامًا استخدام طريقة On Dete المتتالية.الميزة الرئيسية لـ "On Remove cascade" هي أنها تلتقط جميع الأطفال؛قد لا يحدث إجراء تشغيل/تخزين مكتوب مخصص إذا لم يتم ترميزه بشكل صحيح.

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

أليس هذا هو كل ما تعنيه التنمية؟

أحاول تجنب عمليات الحذف أو التحديثات التي لم أطلبها صراحةً في خادم SQL.

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

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

أنا، مثل أي شخص آخر هنا، أجد أن عمليات الحذف المتتالية مفيدة بشكل هامشي فقط (ليس هناك الكثير من العمل لحذف البيانات المرجعية في الجداول الأخرى - إذا كان هناك الكثير من الجداول، يمكنك ببساطة أتمتة ذلك باستخدام برنامج نصي) ولكنها مزعجة حقًا عندما يقوم شخص ما عن طريق الخطأ بحذف بعض البيانات المهمة التي يصعب استعادتها.

الحالة الوحيدة التي سأستخدمها هي إذا كانت البيانات الموجودة في جدول الجدول خاضعة للتحكم بدرجة عالية (على سبيل المثال، أذونات محدودة) ويتم تحديثها أو حذفها فقط من خلال عملية خاضعة للرقابة (مثل تحديث البرنامج) التي تم التحقق منها.

يمكن معالجة الحذف أو التحديث إلى S الذي يزيل قيمة المفتاح الخارجي الموجودة في بعض مجموعات R بإحدى الطرق الثلاث:

  1. الرفض
  2. الانتشار
  3. إبطال.

ويشار إلى الانتشار على أنه متتالية.

هناك حالتان:

‣ إذا تم حذف صف في S، فاحذف صفوف R التي أشارت إليه.

‣ إذا تم تحديث صف في S، قم بتحديث القيمة في صفوف R التي تشير إليه.

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

لقد قمت للتو بتقديم الحذف المتتالي لجدول تقاطع جديد بين جدولين موجودين بالفعل (التقاطع المطلوب حذفه فقط)، بعد أن تم تثبيط الحذف المتتالي لبعض الوقت.كما أنها ليست سيئة للغاية إذا فقدت البيانات.

ومع ذلك، فهو أمر سيئ في جداول القائمة المشابهة للتعداد:يقوم شخص ما بحذف الإدخال 13 - الأصفر من "ألوان" الجدول، ويتم حذف جميع العناصر الصفراء في قاعدة البيانات.وأيضًا، يتم تحديث هذه العناصر أحيانًا بطريقة حذف الكل وإدراج الكل، مما يؤدي إلى حذف التكامل المرجعي تمامًا.بالطبع هذا خطأ، ولكن كيف يمكنك تغيير برنامج معقد تم تشغيله لسنوات عديدة، مع تعرض إدخال التكامل المرجعي الحقيقي لخطر الآثار الجانبية غير المتوقعة؟

هناك مشكلة أخرى وهي متى يجب الاحتفاظ بقيم المفتاح الخارجي الأصلية حتى بعد حذف المفتاح الأساسي.يمكن للمرء إنشاء عمود علامة مميزة وخيار ON DELETE SET NULL لـ FK الأصلي، ولكن هذا يتطلب مرة أخرى مشغلات أو رمزًا محددًا للحفاظ على قيمة المفتاح المتكررة (باستثناء بعد حذف PK).

تعد عمليات الحذف المتتالية مفيدة للغاية عند تنفيذ الكيانات المنطقية من النوع الفائق والنوع الفرعي في قاعدة بيانات فعلية.

عند استخدام جداول منفصلة من النوع الفائق والنوع الفرعي لتنفيذ الأنواع الفائقة/الأنواع الفرعية فعليًا (بدلاً من تجميع جميع سمات النوع الفرعي في جدول نوع فائق فعلي واحد)، يكون هناك خيار واحد -علاقة واحدة بين هذه الجداول والمشكلة تصبح كيفية الحفاظ على مزامنة المفاتيح الأساسية بنسبة 100٪ بين هذه الجداول.

يمكن أن تكون عمليات الحذف المتتالية أداة مفيدة للغاية من أجل:

1) تأكد من أن حذف سجل النوع الفائق يؤدي أيضًا إلى حذف سجل النوع الفرعي المقابل.

2) تأكد من أن أي حذف لسجل نوع فرعي يؤدي أيضًا إلى حذف سجل النوع الفائق.يتم تحقيق ذلك من خلال تنفيذ مشغل حذف "بدلاً من" في جدول النوع الفرعي الذي ينتقل ويحذف سجل النوع الفائق المقابل، والذي بدوره يحذف سجل النوع الفرعي.

يضمن استخدام عمليات الحذف المتتالية بهذه الطريقة عدم وجود أي سجلات من النوع الفائق أو النوع الفرعي اليتيم على الإطلاق، بغض النظر عما إذا قمت بحذف سجل النوع الفائق أولاً أو سجل النوع الفرعي أولاً.

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