it-swarm.asia

كيفية استخدام RESTRICT لمفتاح خارجي في الخلية؟

في هيكل قاعدة البيانات

  CREATE TABLE Country (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE City (
  name varchar(40) NOT NULL,
  PRIMARY KEY  (name)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE Map (
  country varchar(40) NOT NULL,
  city varchar(100) NOT NULL,
  PRIMARY KEY  (country,city),
  FOREIGN KEY (country) REFERENCES Country (name) ON DELETE CASCADE,
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

أتوقع حذف الوالد من City بترك القيمة المقابلة في الطفل سليمة من خلال هذه الأوامر الثلاثة المتساوية

  FOREIGN KEY (city) REFERENCES City (name) ON DELETE NO ACTION
  FOREIGN KEY (city) REFERENCES City (name) ON DELETE RESTRICT
  FOREIGN KEY (city) REFERENCES City (name)

ولكن عند استخدام NO ACTION OR RESTRICT أو حذف ON DELETE. لا يسمح لي MySQL بالحذف من العمود الأصلي الذي يحتوي على هذا الخطأ:

ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails 
('test'.'Map', CONSTRAINT 'Map_ibfk_2' FOREIGN KEY ('city') REFERENCES 'City'('name')
 ON DELETE RESTRICT

اين انا مخطئ؟ أليس من مسؤولية SQL NO ACTION لحذف الوالدين وترك الطفل اليتيم؟

11
Googlebot

وفقًا لـ توثيق MySQL على DELETE RESTRICT

• RESTRICT: يرفض عملية الحذف أو التحديث للجدول الأصل. تحديد RESTRICT (أو NO ACTION) هو نفس حذف جملة ON DELETE أو ON UPDATE.

أما بالنسبة لأي إجراء

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

يحذف DELETE RESTRICT الوالد من الحذف وليس الأطفال.

13
RolandoMySQLDBA

إذا كنت تريد حذف الوالد وترك الطفل ، فأنت على الأرجح تريد ON DELETE SET NULL الخيار:

SET NULL: حذف الصف أو تحديثه من الجدول الأصل ، وتعيين عمود أو أعمدة المفتاح الخارجي في الجدول الفرعي إلى NULL. كل من عبارات ON DELETE SET NULL و ON UPDATE SET NULL مدعومة.

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

هناك الكثير من "لا" في هذه الجملة الأخيرة ، لذا تأكد فقط من أن الوالدين يمكن أن يكون فارغًا.

راجع أيضًا هذا السؤال المرتبط: ما هو الغرض من SET NULL في قيود Delete/Update Foreign Keys؟

من خلال تحديد مفتاح خارجي ، أخبرت قاعدة البيانات بعدم قبول الإدخالات في الجدول التابع التي لا تحتوي على قيمة مقابلة في الأصل.

5
Derek Downey