it-swarm.asia

لماذا لا يتم استخدام مطابقات المفتاح الأساسي / المفتاح الخارجي للانضمام؟

بقدر ما يمكنني العثور على العديد من DBMSs (مثل mysql و postgres و mssql) تستخدم تركيبات fk و pk فقط لتقييد التغييرات على البيانات ، ولكن نادرًا ما يتم استخدامها لتحديد الأعمدة تلقائيًا للانضمام (مثل الارتباط الطبيعي مع الأسماء). لماذا هذا؟ إذا كنت قد حددت بالفعل علاقة بين جدولين باستخدام pk/fk ، فلماذا لا يمكن لقاعدة البيانات أن تكتشف أنه إذا انضممت إلى هذه الجداول ، فأريد الانضمام إليها في أعمدة pk/fk؟

تحرير: لتوضيح هذا قليلا:

افترض أن لدي جدول 1 وجدول 2. يحتوي الجدول 1 على مفتاح خارجي في العمود أ ، والذي يشير إلى المفتاح الأساسي في الجدول 2 ، العمود ب. الآن إذا انضممت إلى هذه الجداول ، فسيتعين علي القيام بشيء مثل هذا:

SELECT * FROM table1
JOIN table2 ON table1.a = table2.b

ومع ذلك ، فقد حددت بالفعل باستخدام مفاتيحي أن table1.a يشير إلى table2.b ، لذلك يبدو لي أنه لا ينبغي أن يكون من الصعب جعل نظام DBMS يستخدم تلقائيًا table1.a و table2.b كأعمدة الصلة ، بحيث يمكن للمرء ببساطة استخدام:

SELECT * FROM table1
AUTO JOIN table2

ومع ذلك ، لا يبدو أن العديد من DBMS يقوم بتنفيذ شيء من هذا القبيل.

49
Tiddo

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

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

دعني أقول ذلك مرة أخرى: بإضافة أعمدة ، فإن الاستعلامات التي لا تستخدم تلك الأعمدة يمكن أن تتحول من "صحيح" إلى "خطأ"!

هذا هو كابوس الصيانة ، بحيث يحظر أي دليل نمط عاقل استخدام هذه الميزة. معظم حظر بالفعل select * لنفس السبب!

كل هذا سيكون مقبولاً ، إذا تم تحسين الأداء. ومع ذلك ، ليس هذا هو الحال.

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

لذلك ليس من المؤكد أن معظم بائعي قواعد البيانات يختارون قضاء وقتهم في أشياء أكثر أهمية.

32
Sjoerd

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

  1. يمكن أن يكون لديك مفاتيح أجنبية متعددة لنفس الجدول. ضع في اعتبارك ما يلي حيث تحتوي الشحنة على نقطة بداية ونقطة نهاية.

    table: USA_States
    StateID
    StateName
    
    table: Shipment
    ShipmentID
    PickupStateID Foreign key
    DeliveryStateID Foreign key
    

    قد ترغب في الانضمام بناءً على حالة الالتقاط. ربما تريد الانضمام إلى حالة التسليم. ربما تريد تنفيذ عمليتي انضمام لكليهما! محرك sql ليس لديه طريقة لمعرفة ما تريد.

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

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

  4. قد تعتقد أن النقطتين 2 و 3 أعلاه ليست ذات صلة نظرًا لأن أسئلتك تتعلق بوقت وجود هي علاقة PK/FK واحدة بين الجداول. ومع ذلك ، فإن وجود PK/FK واحد بين الجداول لا يعني أنه لا يمكنك امتلاك حقول أخرى للانضمام إليها بالإضافة إلى PK/FK. لن يعرف محرك sql الحقول التي تريد الانضمام إليها.

  5. لنفترض أن لديك جدول "USA_States" ، و 5 جداول أخرى مع FK للولايات. تحتوي الجداول "الخمسة" أيضًا على بعض المفاتيح الخارجية لبعضها البعض. هل يجب أن ينضم محرك sql تلقائيًا إلى الجداول "الخمسة" مع "USA_States"؟ أم يجب أن تربط "الخمسة" ببعضها البعض؟ على حد سواء؟ يمكنك إعداد العلاقات بحيث يدخل محرك SQL في حلقة لا نهائية محاولًا ربط الأشياء معًا. في هذه الحالة ، من المستحيل أن يخمن محرك SQL تخمين ما تريده.

باختصار: PK/FK لا علاقة له بالانضمام إلى الجدول. هم أشياء منفصلة لا علاقة لها. إنها مجرد صدفة للطبيعة التي غالبًا ما تنضم إليها في أعمدة PK/FK.

هل تريد أن يخمن محرك SQL ما إذا كان صلة كاملة أو يسارية أو يمينية أو داخلية؟ لا أعتقد ذلك. على الرغم من أن ذلك يمكن أن يكون خطيئة أقل من تخمين الأعمدة للانضمام إليها.

27
Lord Tydus

مفهوم "قابلية الانضمام". علاقات r1 و r2 قابلة للانضمام إذا وفقط إذا كانت السمات التي تحمل نفس الاسم من نفس النوع ... لا ينطبق هذا المفهوم على الانضمام على هذا النحو فحسب ، بل على عمليات أخرى مختلفة [مثل الاتحاد] أيضًا.

SQL والنظرية العلائقية: كيفية كتابة كود SQL دقيق بواسطة C. J. التاريخ

تحتوي SQL القياسية بالفعل على مثل هذه الميزة ، والمعروفة باسم NATURAL JOIN ، وتم تنفيذه في mySQL.

على الرغم من أن اقتراحك لا يستحق تمامًا ، إلا أنه يبدو معقولًا. مع SQL Server (الذي يفتقر إلى الدعم لـ NATURAL JOIN ) ، أستخدم موجه SQL في إدارة الاستوديو: عند كتابة INNER JOIN تقترح InteliSense الخاصة بها ON فقرات استنادًا إلى كل من أسماء السمات الشائعة والمفاتيح الأجنبية وأجدها مفيدة جدًا. ليس لدي رغبة كبيرة في رؤية نوع ربط SQL (قياسي) جديد لهذا ، على الرغم من ذلك.

11
onedaywhen

جاءت SQL أولاً!

جاءت قيود المفاتيح الخارجية والمفاتيح الخارجية في وقت لاحق وهي في الأساس تحسين لتطبيقات نمط "المعاملات".

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

لقد قطعت قواعد البيانات العلائقية شوطا طويلا منذ ذلك الحين ، وهناك استخدام أساسي كطبقة ثبات لأنظمة المعاملات لم يكن ما كانت CODD et. جميع المتوخاة.

ومع ذلك ، فإن هيئة معايير ANSI لجميع أهدافها المتضاربة وسياسات البائعين تسعى دائمًا للحفاظ على خصائص SQL التي يمكن إثباتها رياضيًا.

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

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

9
James Anderson

قد تكون تعمل بناءً على افتراض خاطئ. أنت تقول "بقدر ما يمكنك معرفة ذلك" ولكن لا تقدم أي دليل تجريبي أو إثباتي. إذا كان pk أو fk هو أفضل فهرس للاستعلام فسيتم استخدامه. لا أعرف لماذا ترى هذا ، لكن تخميني هو أن الاستفسارات ضعيفة التكوين.


تحرير الآن بعد أن تمت إعادة كتابة السؤال بالكامل: الحالة التي تصفها ستكون فقط لمجموعة صغيرة جدًا من الاستعلامات. ماذا لو كان هناك 12 منضدة منضمة؟ ماذا لو لم يكن هناك ملفات FKs .... حتى إذا كان هناك صلة افتراضية في أنا ما زلت حدد الصلة دائمًا للقراءة فقط. (لا أريد أن ألقي نظرة على البيانات ثم أحاول اكتشاف ما يتم الانضمام إليه)

تقوم بعض أدوات الاستعلام فعليًا بالانضمام التلقائي لك ثم تسمح لك بإزالة الصلة أو تحريرها. أعتقد أن منشئ الاستعلام الخاص بـ MS Access يقوم بذلك.

وأخيرًا ، ينص معيار ANSII على أنه يجب تحديد الصلة. هذا سبب كافٍ لعدم السماح بذلك.

7
Morons

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

  • قد ترغب في استخدام منتج ديكارت من الجدولين أو جزء منه لبعض الأغراض.
  • قد تكون هناك مجالات أخرى يمكنك الانضمام إليها لغرض آخر.
  • إذا كنت تنضم إلى ثلاثة جداول أو أكثر ، فقد يرتبط أحد الجداول بطاولين أو أكثر من الجداول. في هذه الحالة ، عادة ما تكون واحدة فقط من علاقات FK المحتملة مناسبة في الاستعلام.
7
BillThor

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

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

(ما زالت زوجتي لا تستطيع فهم الفرق بين Management Studio و Sql Server وتتحدث عن بدء خادم sql عندما تبدأ تشغيل استوديو الإدارة!)

3
Ian Ringrose

ينضم الانضمام الطبيعي "تلقائيًا" إلى تكافؤ الأعمدة المشتركة ، ولكن يجب عليك كتابة ذلك فقط إذا كان هذا ما تريده تريده بناءً على معاني الجدول والنتيجة المستحقة. لا يوجد "تلقائي" لمعرفة كيفية ربط جدولين "أو" بأي طريقة أخرى يظهر أي جدول "يجب" في استعلام. لسنا بحاجة إلى معرفة قيود الاستعلام. يعني وجودها فقط أن المدخلات قد تكون محدودة ، وبالتالي قد يكون الناتج أيضًا. يمكنك تحديد نوع من عامل join_on_fk_to_pk الذي ينضم تلقائيًا إلى القيود المعلنة ؛ ولكن إذا كنت تريد أن يظل معنى الاستعلام كما هو إذا تغيرت القيود فقط وليس معاني الجدول ، فسيتعين عليك تغيير هذا الاستعلام إلى ليس استخدام الثوابت المعلنة الجديدة. مجرد إعطاء الاستعلام الذي تريده باستخدام join & condition يترك المعنى كما هو بالفعل على الرغم من أي تغييرات في القيد .

لا تؤثر القيود المفروضة (بما في ذلك PKs و FKs و UNIQUE & CHECK) على ما تعنيه الجداول. بالطبع ، إذا تغيرت معاني الجدول ، فقد تتغير القيود. ولكن إذا تغيرت القيود ، فهذا لا يعني أن الاستعلامات يجب أن تتغير.

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

هل هناك أي قاعدة أساسية لإنشاء استعلام SQL من وصف يمكن قراءته؟

3
philipxy

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

كما أشار آخرون ، تستخدم بعض التطبيقات امتدادًا حيث ينضم (عمود) الانضمام إلى جدولين بناءً على اسم عمود مشترك ، وهو مشابه إلى حد ما. لكنها ليست منتشرة على نطاق واسع. لاحظ أن هذا الامتداد يختلف عن SELECT * FROM employee NATURAL JOIN department; بناء الجملة الذي لا يتضمن طريقة لتحديد الأعمدة التي سيتم استخدامها. لا تعتمد على علاقة بين الجداول ، مما يجعلها غير موثوقة (بناء الصلة الطبيعية أكثر من الامتداد).

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

2
jmoreno

إذا كان من المفترض أن يؤدي حذف عبارة ON إلى اتباع الحقول بناءً على التكامل المرجعي ، فكيف يمكنك القيام بمنتج ديكارت؟

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

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

1
JeffO