سؤال

لقد كنت أتعلم SQL ببطء في الأسابيع القليلة الماضية.لقد التقطت كل الجبر العلائقي وأساسيات كيفية عمل قواعد البيانات العلائقية.ما أحاول القيام به الآن هو معرفة كيفية تنفيذه.

حجر العثرة الذي واجهته في هذا هو المفاتيح الخارجية في MySQL.لا يبدو أنني أجد الكثير عن الآخرين غير الموجودين في InnoDB مخطط التخزين الذي يحتوي عليه MySQL.

ما هو المثال البسيط للمفاتيح الخارجية المطبقة في MySQL؟

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

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories,
Foreign Key(`uID`) references users
) ENGINE=InnoDB;
هل كانت مفيدة؟

المحلول

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

CREATE TABLE `posts` (
`pID` bigint(20) NOT NULL auto_increment,
`content` text NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`uID` bigint(20) NOT NULL,
`wikiptr` bigint(20) default NULL,
`cID` bigint(20) NOT NULL,
PRIMARY KEY  (`pID`),
Foreign Key(`cID`) references categories(`cID`),
Foreign Key(`uID`) references users(`uID`)
) ENGINE=InnoDB;

ومطلوب اسم العمود في بند references.

نصائح أخرى

تم التعديل: يذكر روبرت وفينكو أنك بحاجة إلى الإعلان عن اسم العمود المشار إليه في قيد المفتاح الخارجي.يعد ذلك ضروريًا في InnoDB، على الرغم من أنه يُسمح لك في SQL القياسية بحذف اسم العمود المشار إليه إذا كان هو نفس الاسم في الجدول الأصلي.

إحدى الخصائص التي واجهتها في MySQL هي أن إعلان المفتاح الخارجي سوف يفشل بصمت في عدة ظروف:

  • لا يتضمن تثبيت MySQL محرك innodb
  • لا يقوم ملف تكوين MySQL الخاص بك بتمكين محرك innodb
  • لا تعلن عن الجدول الخاص بك باستخدام معدّل الجدول ENGINE=InnoDB
  • عمود المفتاح الخارجي ليس بالضبط نفس نوع البيانات مثل عمود المفتاح الأساسي في الجدول المشار إليه

لسوء الحظ، لا تعطي MySQL أي رسالة تفيد بفشلها في إنشاء قيد المفتاح الخارجي.إنه ببساطة يتجاهل الطلب، ويقوم بإنشاء الجدول بدون المفتاح الخارجي (إذا قمت بإظهار منشورات إنشاء جدول، فقد لا ترى أي تعريف للمفتاح الخارجي).لقد اعتقدت دائمًا أن هذه ميزة سيئة في MySQL!

نصيحة: الوسيطة الصحيحة لأنواع البيانات الصحيحة (على سبيل المثالBIGINT(20)) ليس ضروريًا.لا علاقة له بحجم التخزين أو نطاق العمود.BIGINT دائمًا بنفس الحجم بغض النظر عن الوسيطة التي تقدمها.يشير الرقم إلى عدد الأرقام التي ستضعها MySQL في العمود إذا كنت تستخدم معدّل العمود ZEROFILL.

هذا لديه بعض كود يوضح كيفية إنشاء مفاتيح خارجية في حد ذاتها، وفي CREATE TABLE.

وهنا واحد من الأمثلة أبسط من ذلك:

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

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;

وأنا أتفق مع روبرت. كنت في عداد المفقودين اسم العمود في بند المراجع (ويجب أن يكون الحصول على خطأ 150). سأضيف أنه يمكنك التحقق من كيفية الجداول حصلت إنشاؤها في الواقع مع:

SHOW CREATE TABLE posts;

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

وكلما قمت بذلك equijoin ، كنت المساواة مفتاح خارجي إلى شيء، وعادة ما المفتاح هو يحيل. مثال:

select *
from 
   Students
inner join
   StudentCourses
on Students.StudentId = StudentCourses.StudentId

وStudentCourses.StudentId هو مفتاح Students.StudentId المراجع الأجنبية.

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