واحد أو اثنين من المفاتيح الأساسية في جدول كثير إلى كثير؟

StackOverflow https://stackoverflow.com/questions/38870

سؤال

لدي الجداول التالية في قاعدة البيانات الخاصة بي والتي لها علاقة متعدد بمتعدد، والتي يتم التعبير عنها من خلال جدول متصل يحتوي على مفاتيح خارجية للمفاتيح الأساسية لكل جدول من الجداول الرئيسية:

  • القطعة:معرف القطعة (PK)، العنوان، السعر
  • مستخدم:معرف المستخدم (PK)، الاسم الأول، اسم العائلة

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

  1. أدوات المستخدم 1:معرف المستخدم (PK)، معرف المستخدم (FK)، معرف المستخدم (FK)
  2. أدوات المستخدم 2:معرف القطعة (PK، FK)، معرف المستخدم (PK، FK)

يحتوي الخيار 1 على عمود واحد للمفتاح الأساسي.ومع ذلك، يبدو هذا غير ضروري نظرًا لأن البيانات الوحيدة التي يتم تخزينها في الجدول هي العلاقة بين الجدولين الأساسيين، ويمكن لهذه العلاقة نفسها أن تشكل مفتاحًا فريدًا.مما يؤدي إلى الخيار 2، الذي يحتوي على مفتاح أساسي مكون من عمودين، ولكنه يفقد المعرف الفريد المكون من عمود واحد الذي يحتوي عليه الخيار 1.يمكنني أيضًا إضافة فهرس فريد مكون من عمودين (WidgetID، UserID) إلى الجدول الأول.

هل هناك أي فرق حقيقي بين الاثنين من حيث الأداء، أو أي سبب لتفضيل نهج واحد على الآخر لتنظيم جدول UserWidgets متعدد إلى متعدد؟

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

المحلول

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

اذهب مع الخيار 2.

نصائح أخرى

انا شخصيا كان لديك عمود المفتاح الاصطناعي/البديل في جداول متعدد إلى متعدد للأسباب التالية:

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

المفتاح الاصطناعي ليس بديلاً للمفتاح الطبيعي/المركب ولا يصبح PRIMARY KEY لهذا الجدول فقط لأنه العمود الأول في الجدول، لذلك أتفق جزئيًا مع مقالة جوش بيركوس.ومع ذلك، لا أوافق على أن المفاتيح الطبيعية هي دائمًا مرشحة جيدة لها PRIMARY KEY's وبالتأكيد لا ينبغي استخدامها إذا كان سيتم استخدامها كمفاتيح خارجية في جداول أخرى.

يستخدم الخيار 2 مفتاح مركب بسيط، ويستخدم الخيار 1 أ مفتاح بديل.يُفضل الخيار 2 في معظم السيناريوهات وهو قريب من النموذج العقلاني من حيث أنه مفتاح مرشح جيد.

هناك مواقف قد ترغب فيها في استخدام مفتاح بديل (الخيار 1)

  1. لا تعلم أن المفتاح المركب يعد مفتاحًا مرشحًا جيدًا بمرور الوقت.خاصة مع البيانات الزمنية (البيانات التي تتغير بمرور الوقت).ماذا لو أردت إضافة صف آخر إلى جدول UserWidget بنفس معرف المستخدم وWidgetId؟فكر في التوظيف (EmployeeId،EmployeeId) - سيعمل في معظم الحالات إلا إذا عاد شخص ما إلى العمل لدى نفس صاحب العمل في وقت لاحق
  2. إذا كنت تقوم بإنشاء رسائل/معاملات تجارية أو شيء مشابه يتطلب مفتاحًا أسهل للاستخدام للتكامل.النسخ ربما؟
  3. إذا كنت ترغب في إنشاء آليات التدقيق الخاصة بك (أو ما شابه ذلك) ولا تريد أن تصبح المفاتيح طويلة جدًا.

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

لذا، استخدم الخيار 2، ولكن تأكد من أن لديك النموذج الكامل.

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

على سبيل المثال، إذا كنت تريد تتبع جميع الأوقات التي استخدم فيها المستخدم 1 عنصر واجهة المستخدم 664 في جدول عنصر واجهة المستخدم، فإن معرف المستخدم ومعرف عنصر واجهة المستخدم لم يعدا فريدين بعد الآن.

ما فائدة المفتاح الأساسي في هذا السيناريو؟فكر في خيار عدم وجود مفتاح أساسي:أدوات المستخدم3:معرف القطعة (FK)، معرف المستخدم (FK)

إذا كنت تريد التفرد، فاستخدم إما المفتاح المركب (UserWidgets2) أو قيد التفرد.

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

الخيار 2 هو الإجابة الصحيحة، إلا إذا كان لديك سبب وجيه لإضافة مفتاح رقمي بديل (وهو ما قمت به في الخيار 1).

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

يجب على أي شخص يقوم ببناء قاعدة بيانات أن يقرأ هذه المقالة http://it.toolbox.com/blogs/database-soup/primary-keyvil-part-i-7327 بواسطة جوش بيركوس لفهم الفرق بين أعمدة المفاتيح الرقمية البديلة والمفاتيح الأساسية.

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

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

سأذهب مع كليهما.

أستمع لي:

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

لكن:لقد واجهت كل أنواع المشاكل في جعل وضع السبات يعمل بشكل صحيح إلا إذا كنت تستخدم مفتاحًا أساسيًا واحدًا تم إنشاؤه - وهو مفتاح بديل.

لذلك سأستخدم البيانات المنطقية والمادية نموذج.المنطقي لديه المفتاح المركب.النموذج المادي - الذي ينفذ النموذج المنطقي - لديه المفتاح البديل والمفاتيح الخارجية.

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

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

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

لذا:

userwidgets( widgetid(fk), userid(fk),
             unique_index(widgetid, userid)
)

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

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