بديل مقابل المفتاح الطبيعي:أرقام صعبة على اختلافات الأداء؟
-
22-07-2019 - |
سؤال
هناك نقاش صحي بين المفاتيح البديلة والطبيعية:
رأيي، الذي يبدو أنه يتماشى مع الأغلبية (إنها أغلبية ضئيلة)، هو أنه يجب عليك استخدام مفاتيح بديلة ما لم يكن المفتاح الطبيعي واضحًا تمامًا ومضمونًا بعدم التغيير.ثم يجب عليك فرض التفرد على المفتاح الطبيعي.مما يعني وجود مفاتيح بديلة في كل الأوقات تقريبًا.
مثال على الطريقتين، بدءاً بجدول الشركة:
1:مفتاح بديل:يحتوي الجدول على حقل معرف وهو PK (والهوية).يجب أن تكون أسماء الشركات فريدة حسب الولاية، لذلك يوجد قيد فريد هناك.
2:المفتاح الطبيعي:يستخدم الجدول اسم الشركة والحالة باعتبارهما PK - يفي بكل من PK والتفرد.
لنفترض أن شركة PK مستخدمة في 10 جداول أخرى.فرضيتي، مع عدم وجود أرقام تدعمها، هي أن النهج الرئيسي البديل سيكون أسرع بكثير هنا.
الحجة المقنعة الوحيدة التي رأيتها للمفتاح الطبيعي هي وجود جدول متعدد إلى متعدد يستخدم المفتاحين الخارجيين كمفتاح طبيعي.أعتقد أنه في هذه الحالة يكون الأمر منطقيًا.ولكن يمكن أن تقع في مشكلة إذا كنت بحاجة إلى إعادة البناء؛هذا خارج نطاق هذا المنصب على ما أعتقد.
هل رأى أحد مقالا يقارن اختلافات الأداء على مجموعة من الجداول التي تستخدم مفاتيح بديلة ضد. نفس مجموعة الجداول باستخدام مفاتيح طبيعية؟إن البحث في SO وGoogle لم يسفر عن أي شيء جدير بالاهتمام، فقط الكثير من صياغة النظريات.
تحديث مهم:لقد بدأت في بناء أ مجموعة من جداول الاختبار التي تجيب على هذا السؤال.تبدو هكذا:
- Partnatural - جدول الأجزاء الذي يستخدم العدد الفريد من نوعه كـ PK
- Partsurgate - جدول الأجزاء الذي يستخدم معرف (int ، الهوية) كـ PK وله فهرس فريد على العدد
- المصنع - معرف (كثافة العمليات، الهوية) كـ PK
- مهندس - معرف (كثافة العمليات، الهوية) كما PK
يتم ربط كل جزء بالمصنع ويتم ربط كل جزء في المصنع بالمهندس.إذا كان لدى أي شخص مشكلة مع هذا الاختبار، فهذا هو الوقت المناسب.
المحلول
استخدم الأثنين!تمنع المفاتيح الطبيعية تلف قاعدة البيانات (قد يكون عدم الاتساق كلمة أفضل).عندما يكون أداء المفتاح الطبيعي "الصحيح" (لإزالة الصفوف المكررة) سيئًا بسبب الطول أو عدد الأعمدة المعنية، لأغراض الأداء، يمكن إضافة مفتاح بديل أيضًا لاستخدامه كمفاتيح خارجية في جداول أخرى بدلاً من المفتاح الطبيعي...ولكن يجب أن يظل المفتاح الطبيعي كمفتاح بديل أو فهرس فريد لمنع تلف البيانات وفرض اتساق قاعدة البيانات...
قد يكون الكثير من الهوه (في "النقاش" حول هذه المسألة) بسبب الافتراض الخاطئ - وهو أنه يجب عليك استخدام المفتاح الأساسي للصلات والمفاتيح الخارجية في الجداول الأخرى.هذا غير صحيح.يمكنك استخدام أي مفتاح كهدف للمفاتيح الخارجية في الجداول الأخرى.يمكن أن يكون المفتاح الأساسي، أو مفتاحًا بديلاً، أو أي فهرس فريد أو قيد فريد.أما بالنسبة للصلات، يمكنك استخدام أي شيء على الإطلاق لشرط الصلة، ولا يجب أن يكون مفتاحًا أو فهرسًا أو حتى فريدًا !!(على الرغم من أنه إذا لم يكن فريدًا، فسوف تحصل على صفوف متعددة في المنتج الديكارتي الذي يقوم بإنشائه).
نصائح أخرى
تختلف المفاتيح الطبيعية عن المفاتيح البديلة في القيمة وليس النوع.
يمكن استخدام أي نوع لمفتاح بديل، مثل VARCHAR
للنظام المولد slug
أو أي شيء آخر.
ومع ذلك، فإن الأنواع الأكثر استخدامًا للمفاتيح البديلة هي INTEGER
و RAW(16)
(أو أي نوع الخاص بك RDBMS
يستخدم ل GUID
'س)،
مقارنة الأعداد الصحيحة البديلة والأعداد الصحيحة الطبيعية (مثل SSN
) يستغرق نفس الوقت بالضبط.
مقارنة VARCHAR
يجب أخذ الترتيب في الاعتبار، وهي بشكل عام أطول من الأعداد الصحيحة، مما يجعلها أقل كفاءة.
مقارنة مجموعة من اثنين INTEGER
ربما يكون أيضًا أقل كفاءة من مقارنة واحدة INTEGER
.
في أنواع البيانات الصغيرة الحجم، من المحتمل أن يكون هذا الاختلاف النسب المئوية من النسب المئوية من الوقت اللازم لجلب الصفحات، واجتياز الفهارس، والحصول على مزالج قاعدة البيانات وما إلى ذلك.
وهنا الأرقام (في MySQL
):
CREATE TABLE aint (id INT NOT NULL PRIMARY KEY, value VARCHAR(100));
CREATE TABLE adouble (id1 INT NOT NULL, id2 INT NOT NULL, value VARCHAR(100), PRIMARY KEY (id1, id2));
CREATE TABLE bint (id INT NOT NULL PRIMARY KEY, aid INT NOT NULL);
CREATE TABLE bdouble (id INT NOT NULL PRIMARY KEY, aid1 INT NOT NULL, aid2 INT NOT NULL);
INSERT
INTO aint
SELECT id, RPAD('', FLOOR(RAND(20090804) * 100), '*')
FROM t_source;
INSERT
INTO bint
SELECT id, id
FROM aint;
INSERT
INTO adouble
SELECT id, id, value
FROM aint;
INSERT
INTO bdouble
SELECT id, id, id
FROM aint;
SELECT SUM(LENGTH(value))
FROM bint b
JOIN aint a
ON a.id = b.aid;
SELECT SUM(LENGTH(value))
FROM bdouble b
JOIN adouble a
ON (a.id1, a.id2) = (b.aid1, b.aid2);
t_source
هو مجرد طاولة وهمية مع 1,000,000
صفوف.
aint
و adouble
, bint
و bdouble
تحتوي على نفس البيانات بالضبط، باستثناء ذلك aint
لديه عدد صحيح مثل أ PRIMARY KEY
, ، بينما adouble
لديه زوج من الأعداد الصحيحة المتطابقة.
على جهازي، يتم تشغيل كلا الاستعلامين لمدة 14.5 ثانية، +/- 0.1 ثانية
فرق الأداء، إن وجد، يقع ضمن نطاق التقلبات.