أدوات المطور · مولد UUID
عشوائي UUID المفاتيح الأساسية وتجزئة B-Tree: ما الذي يحدث بالفعل
· لماذا يهم
uuid التشفير متصفح API
يتم إدراج مفاتيح v4 العشوائية في صفحات الفهرس العشوائية، وتدفع الفهارس المجمعة ثمنها. يشرح هذا المنشور الآلية، وتكلفة تخزين النص مقابل الثنائي، وأين تقوم UUIDs المرتبة بالوقت بتغيير الصورة.
تتباطأ عمليات الإدخال مع نمو الجدول - وهو العرض الذي يدفع مسؤولي قواعد البيانات إلى النظر في اختيارهم الرئيسي
يؤدي إدراج صف يحتوي على UUID عشوائيًا كمفتاح أساسي في قاعدة بيانات ذات فهرس متفاوت المسافات إلى قيام قاعدة البيانات بإدراج الصف الجديد في موقع عشوائي داخل بنية الشجرة B. يتم إلحاق المفاتيح التسلسلية بالصفحة الموجودة في أقصى اليمين، مع الاحتفاظ بجميع الإدخالات داخل منطقة صغيرة مقيمة في ذاكرة التخزين المؤقت. تقوم المفاتيح العشوائية بتوزيع الإدخالات عبر الفهرس بأكمله، مما يجبر قاعدة البيانات على اجتياز وتعديل الصفحات المتباعدة في التخزين الفعلي. مع نمو الجدول وتعمق الشجرة، فإن كل إدراج يمس المزيد من الصفحات ويتسبب في المزيد من عمليات I/O. العملية التي بدت رخيصة بألف صف تصبح مكلفة بمليون. هذه ليست مشكلة نظرية. يتجلى في تدهور قابل للقياس في إنتاجية الإدراج.
كيف يتم تعبئة شجرة B المجمعة - يتم إلحاق المفاتيح التسلسلية بالصفحة الأخيرة؛ مفاتيح عشوائية تلمس الصفحات عبر الفهرس بأكمله
تعتبر الآلية أساسية لكيفية عمل B-trees لأنها تحافظ على ترتيب المفاتيح المفرزة داخل الصفحات الورقية. عند إدراج صف يحتوي على المفتاح 10,001 في جدول يحتوي بالفعل على المفاتيح 1 حتى 10,000، تعرف قاعدة البيانات مكان هذا الصف: في النهاية، في الصفحة الموجودة في أقصى اليمين إذا كانت هناك مساحة، أو في صفحة جديدة ملحقة باليمين. عند إدراج صف يحتوي على UUID عشوائي مثل 7524fae2-7dec-11d0-a765-00a0c91e6bf6 في نفس الجدول، يجب أن تتنقل قاعدة البيانات في الشجرة للعثور على الصفحة الطرفية التي تحتوي على مفاتيح في النطاق UUID، وتحديد الموضع الدقيق داخل تلك الصفحة وإدراج الصف. إذا كانت تلك الصفحة ممتلئة، فإنها تنقسم، وتنقل نصف محتوياتها إلى صفحة جديدة وتحديث العقدة الأصلية.
انقسامات الصفحة وضغط ذاكرة التخزين المؤقت - لماذا يكلف الإدراج العشوائي المزيد من I/O ولماذا ينمو التأثير مع حجم الجدول
تقوم المفاتيح العشوائية بإنشاء نمط إدراج أسوأ حالة لأن كل إدراج يقع في موضع عشوائي في الشجرة بدلاً من إلحاقه بالصفحة الموجودة في أقصى اليمين. يجب أن تبحث قاعدة البيانات عن الصفحة الصحيحة، وهو ما يكلف عادةً عدة عمليات قراءة للصفحات - واحدة لكل مستوى من الشجرة. ثم يجب عليها تعديل تلك الصفحة، مما قد يؤدي إلى انقسام ينتشر إلى أعلى الشجرة. يتم تعديل المزيد من الصفحات، وتحدث المزيد من عمليات الكتابة، ويمتلئ مخزن المخزن المؤقت للذاكرة بصفحات من مناطق مختلفة من الشجرة بدلاً من التركيز على نقطة الإدراج النشطة. تزداد نسبة تفويت ذاكرة التخزين المؤقت ويصبح I/O هو عنق الزجاجة، مع استقرار معدل الإدراج مع نمو الجدول إلى مقاييس أكبر.
نص أو ثنائي - 36-سلاسل أحرف مقابل 16-بايت uuid أصلي أو ثنائي (16) الأعمدة والتأثير على حجم الفهرس
التكلفة ليست موحدة عبر محركات قواعد البيانات لأن الأنظمة المختلفة تعمل على تحسين إدارة الصفحات بشكل مختلف. قد تظهر قواعد البيانات ذات الضغط القوي أو أحجام الصفحات الصغيرة أو العمليات داخل الذاكرة اختلافات أصغر في الأداء بين المفاتيح التسلسلية والعشوائية. ستظهر قواعد البيانات ذات الصفحات الكبيرة أو الأقراص الميكانيكية أو حدود الذاكرة الصارمة تدهورًا كبيرًا. المشكلة ملحوظة وقابلة للقياس: قم بقياس معدلات الإدراج عند 1,000 من الصفوف، و100,000 من الصفوف، و1,000,000 من الصفوف. إذا انخفض معدل الثانية بشكل حاد على المقاييس الأكبر، فإنك تواجه عقوبة الإدراج العشوائي مع تكوين الأجهزة وقاعدة البيانات المحددة لديك.
البدائل مرتبة زمنيًا - كيف يحافظ UUIDv7 وULID على التفرد أثناء الإدراج في نهاية الفهرس
تستهلك UUIDs كسلاسل 36 حرفًا في نموذج نصي أو 16 bytes كنوع UUID ثنائي اعتمادًا على تنسيق التخزين المختار. سلسلة الأحرف 36 في عمود UTF-8 أو ASCII هي 36 bytes، مقارنة بـ 8 bytes لعدد صحيح يبلغ 64 بت. الفهرس الموجود في عمود السلسلة UUID أكبر بثلاث مرات من الفهرس الموجود في عمود عدد صحيح، بافتراض عدم تطبيق أي تقنيات ضغط. تعني الفهارس الأكبر عددًا أقل من صفحات الفهرس التي يتم احتواؤها في تجمع المخزن المؤقت، مما يعني عددًا أقل من مرات الوصول إلى ذاكرة التخزين المؤقت عند اجتياز الشجرة. يؤدي الفهرس الأصغر الذي يناسب RAM أداءً أفضل من الفهرس الكبير الذي يجب قراءته من القرص في كل استعلام، بغض النظر عن ترتيب الإدراج أو أنماط عبء العمل.
مثال عملي - نفس عبء عمل الإدراج الموصوف لمفتاح عشوائي وجدول مفاتيح مرتب زمنيًا، من الناحية النوعية، دون معايير مخترعة
فرق التخزين مهم بشكل كبير لكل من الفهارس الأساسية والثانوية لأن كل فهرس ثانوي يتضمن المفتاح الأساسي يجب أن يخزن كامل 36-حرف UUID أو 16 بايت ثنائي القيمة UUID. وهذا يجعل الفهارس الثانوية أكبر بكثير من الفهارس التي تستخدم مفتاحًا صحيحًا لعمليات البحث عن المفتاح الأساسي. النسخ المتماثل والنسخ الاحتياطي ومجموعات نتائج الاستعلام كلها تنمو بشكل متناسب مع حجم الفهرس الأكبر. يُنتج المولد ToolAcre UUID قيمًا ثنائية متوافقة؛ يؤدي تخزينها كأنواع ثنائية (16) أو GUID اعتمادًا على قاعدة البيانات إلى توفير المساحة مقارنةً بـ varchar(36) وتحسين كفاءة ذاكرة التخزين المؤقت في جميع المجالات. يعد تحسين التخزين هذا أمرًا بالغ الأهمية للأنظمة واسعة النطاق.
ما لا يغطيه هذا - الجداول وقواعد البيانات المنظمة في الكومة حيث لا يتم تجميع المفتاح الأساسي، حيث يكون التأثير أصغر
أحد التحسينات الشائعة هو تخزين UUID كثنائي داخليًا وعرضه كسلسلة فقط عند الحاجة لواجهات برمجة التطبيقات أو واجهات المستخدم. تعمل عمليات الفهرس والانضمام على النموذج الثنائي المضغوط؛ يتم تحويل الاستجابة API أو رمز التطبيق إلى تمثيل سلسلة. توفر بعض قواعد البيانات أنواع GUID أو UUID المضمنة التي تتعامل مع هذا التحويل تلقائيًا. ويتطلب البعض الآخر عمليات صب صريحة. فرق الأداء بين أعمدة 36 بايت و 16 بايت حقيقي: جدول يحتوي على مليون صف ومفتاح عمود 36 بايت مقابل 16 بايت UUID يختلف بمقدار 20 MB لكل مستوى فهرس، والذي يمكن أن يكون الفرق بين الفهرس الملائم ذاكرة التخزين المؤقت L3 وتتطلب جلب الذاكرة.
الخلاصة: تعرف على الفهرس الخاص بك قبل اختيار الإصدار — يُنتج المولد ToolAcre معرفات UUID عشوائية؛ استخدم المنشور لتحديد ما إذا كان ذلك يناسب محرك التخزين الخاص بك
تتطلب المفاضلة بين أداء الإدراج وحجم الفهرس وخصائص الاستعلام قرارات معمارية تعتمد على أنماط عبء العمل. يمكن أن يكون مفتاح السلسلة المتسلسل سريع الإدخال إذا كانت السلاسل تصاعدية، على سبيل المثال، السلاسل المستندة إلى الطابع الزمني، ولكنها ستستهلك نفس المساحة مثل UUID العشوائية وتسرب المعلومات المؤقتة. يعد UUID العشوائي أكثر نظافة من الناحية الدلالية ولا يحتوي على مكون طابع زمني للتسريب، ولكنه أبطأ في إدراجه في فهرس متفاوت المسافات وأكبر في مساحة التخزين بشكل عام. تجمع البدائل المرتبة زمنيًا مثل UUIDv7 بين الفوائد من خلال الحفاظ على منطقة الإدراج مع تجنب تسرب الطابع الزمني في الإصدار 4 من المعرفات العشوائية.