it-swarm.asia

الفرق بين On Cascade و On Update Cascade في الخلية

لدي جدولان في قاعدة بيانات MySQL - parent، child. أحاول إضافة مراجع رئيسية أجنبية إلى جدول أعمالي بناءً على الجدول الأصلي. هل هناك فرق كبير بين ON UPDATE CASCADE و ON DELETE CASCADE

مائدتي الرئيسية

CREATE TABLE parent (
    id INT NOT NULL,
    PRIMARY KEY (id)
) ENGINE=INNODB;

سؤالي هو: ما الفرق بين استعلامات SQL التالية.

  1. ON DELETE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON DELETE CASCADE
    ) ENGINE=INNODB;
    
  2. ON UPDATE CASCADE

    CREATE TABLE child (
        id INT, 
        parent_id INT,
        INDEX par_ind (parent_id),
        FOREIGN KEY (parent_id) 
            REFERENCES parent(id)
            ON UPDATE CASCADE
    ) ENGINE=INNODB;
    
  3. ON UPDATE CASCADE ON DELETE CASCADE

    CREATE TABLE child (
            id INT, 
            parent_id INT,
            INDEX par_ind (parent_id),
            FOREIGN KEY (parent_id) 
                REFERENCES parent(id)
                ON UPDATE CASCADE ON DELETE CASCADE
        ) ENGINE=INNODB;
    

هل هناك أخطاء في الاستفسارات؟ ماذا تعني هذه الاستفسارات (1،2 و 3) ؟؟ هل هم نفس ؟؟؟

53
Lonewolf

يمكن العثور على سلسلة جيدة جدًا حول هذا الموضوع هنا وأيضًا هنا . الدليل النهائي لـ MySQL هو بالطبع الوثائق التي يمكن العثور عليها هنا .

يوجد في معيار SQL 2003 5 إجراءات مرجعية مختلفة:

  1. تتالي
  2. بتقييد
  3. لا رد فعل
  4. تعيين فارغ
  5. الوضع الإفتراضي

للإجابة على السؤال:

  1. [~ # ~] شلال [~ # ~]

    • ON DELETE CASCADE يعني أنه إذا تم حذف السجل الأصلي ، فسيتم أيضًا حذف أي سجلات فرعية. هذه ليست فكرة جيدة في رأيي. يجب عليك تتبع جميع البيانات الموجودة في أي قاعدة بيانات ، على الرغم من أنه يمكن القيام بذلك باستخدام TRIGGERs. (ومع ذلك ، انظر التحذير في التعليقات أدناه).

    • ON UPDATE CASCADE يعني أنه إذا تم تغيير المفتاح الأساسي الرئيسي ، فستتغير القيمة الفرعية أيضًا لتعكس ذلك. مرة أخرى في رأيي ، ليست فكرة عظيمة. إذا كنت تغير PRIMARY KEYs بأي انتظام (أو حتى على الإطلاق!) ، هناك خطأ في التصميم الخاص بك. مرة أخرى ، انظر التعليقات.

    • ON UPDATE CASCADE ON DELETE CASCADE يعني أنه إذا UPDATE [~ # ~] أو [~ # ~] DELETE الوالد ، التغيير متتالية للطفل. وهذا يعادل AND لنتائج نتائج أول جملتين.

  2. [~ # ~] تقييد [~ # ~]

    • RESTRICT يعني أن أي محاولة لحذف و/أو تحديث أحد الوالدين ستفشل في إلقاء خطأ. هذا هو السلوك الافتراضي في حالة عدم تحديد إجراء مرجعي صراحة.

      للحصول على ON DELETE أو ON UPDATE غير محدد ، الإجراء الافتراضي دائمًا RESTRICT`.

  3. لا يوجد إجراء

    • NO ACTION: من يدوي . كلمة أساسية من SQL القياسية. في MySQL ، ما يعادل RESTRICT. يرفض MySQL Server عملية الحذف أو التحديث للجدول الأصل إذا كانت هناك قيمة مفتاح خارجي ذات صلة في الجدول المشار إليه. بعض أنظمة قواعد البيانات لها تأجيلات الشيكات و NO ACTION هو شيك مؤجل. في MySQL ، يتم التحقق من قيود المفتاح الخارجي على الفور ، لذلك NO ACTION هو نفسه RESTRICT.
  4. SET NULL

    • SET NULL - مرة أخرى من الدليل. احذف الصف أو قم بتحديثه من الجدول الأصل ، وقم بتعيين عمود أو أعمدة المفتاح الخارجي في الجدول الفرعي إلى NULL. هذه ليست أفضل الأفكار IMHO ، في المقام الأول لأنه لا توجد طريقة "السفر عبر الزمن" - أي النظر إلى الجداول الفرعية وربط السجلات بـ NULLs مع السجل الرئيسي ذي الصلة - إما CASCADE أو استخدم TRIGGERs لملء جداول التسجيل لتتبع التغييرات (ولكن ، انظر التعليقات).
  5. تعيين الافتراضي

    • SET DEFAULT. جزء آخر (قد يكون مفيدًا جدًا) من معيار SQL لم يزعج MySQL تنفيذه! يسمح للمطور بتحديد قيمة يتم تعيين عمود (أعمدة) المفاتيح الخارجية فيها على UPDATE أو DELETE. سيرفض InnoDB و NDB تعريفات الجدول مع SET DEFAULT بند.

كما ذكرنا أعلاه ، يجب أن تقضي بعض الوقت في النظر إلى الوثائق ، هنا .

76
Vérace

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

إذا قمت بتنفيذ:

UPDATE parent SET id = -1 WHERE id = 1;

وهناك سجل واحد على الأقل في child مع parent_id = 1 ، 1) ستفشل ؛ في الحالتين 2) و 3) ، يتم تحديث جميع السجلات ذات الأصل_الأحد = 1 إلى القيمة_الآلية = -1.

إذا قمت بتنفيذ:

DELETE FROM parent WHERE id = 1;

وهناك سجل واحد على الأقل في child مع parent_id = 1 ، 2) ستفشل ؛ في الحالتين 1) و 3) ، جميع السجلات مع parent_id = 1 تم حذفها.

3) صحيح من الناحية النحوية.

الوثائق الكاملة يمكن العثور عليها في الدليل .

9
jynus

ليس لدي سمعة كافية للتعليق على الإجابات السابقة. لذا اعتقدت أنني سأفصل قليلاً.

1) عند حذف CASCADE يعني إذا تم حذف السجل الأصلي ، فسيتم أيضًا حذف أي سجلات فرعية مرجعية. عند تحديث الإعدادات الافتراضية لـ RESTRICT ، مما يعني أن UPDATE في السجل الرئيسي سيفشل.

2) ON DELETE إجراء افتراضيات RESTRICT ، مما يعني فشل DELETE في السجل الأصلي. في UPDATE CASCADE سيتم تحديث جميع السجلات الفرعية المرجعية عند تحديث السجل الرئيسي.

3) انظر إجراءات CASCADE في 1) و 2) أعلاه.

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

6
g r