متى تضطر حقًا إلى استخدام UUID كجزء من التصميم؟

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

  •  22-08-2019
  •  | 
  •  

سؤال

أنا لا أرى حقا نقطة UUID.أعلم أن احتمال الاصطدام هو لا شيء على نحو فعال, ، لكن لا شيء على نحو فعال ليست حتى قريبة من المستحيل.

هل يمكن لأي شخص أن يعطي مثالاً حيث ليس لديك خيار سوى استخدام UUID؟من جميع الاستخدامات التي رأيتها، أستطيع أن أرى تصميمًا بديلاً بدون UUID.من المؤكد أن التصميم قد يكون أكثر تعقيدًا بعض الشيء، ولكن على الأقل لا يحتوي على احتمالية فشل غير صفرية.

UUID تنبعث منه رائحة المتغيرات العالمية بالنسبة لي.هناك العديد من الطرق التي تجعل المتغيرات العامة تصميمًا أبسط، لكنه مجرد تصميم كسول.

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

المحلول

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

والإصدار 4 UUIDs هي أساسا بايت فقط 16 من العشوائية سحبها من مولد رقم عشوائي آمن مشفر، مع بعض لتحديد إصدار UUID والبديل-twiddling قليلا. ومن غير المرجح للغاية أن يصطدم، لكنه يمكن أن يحدث إذا تم استخدام PRNG أو إذا كنت يحدث لمجرد الحصول على حقا، حقا، حقا، حقا، حقا سيئة الحظ.

والإصدار 5 والإصدار 3 UUIDs تستخدم SHA1 وظائف تجزئة MD5 على التوالي، إلى الجمع بين مساحة الاسم مع قطعة من بيانات فريدة بالفعل لتوليد UUID. هذا سوف، على سبيل المثال، تسمح لك لإنتاج UUID من URL. اصطدام هنا فقط ممكن إذا لديه وظيفة التجزئة الأساسية أيضا حدوث تصادم.

والإصدار 1 UUIDs هي الأكثر شيوعا. وهم يستخدمون عنوان بطاقة الشبكة MAC (وهو ما لم المغشوش، يجب أن تكون فريدة من نوعها)، بالإضافة إلى الطابع الزمني، بالإضافة إلى المعتاد بت twiddling لتوليد UUID. في حالة وجود جهاز لم يكن لديك عنوان MAC، يتم إنشاء بايت عقدة 6 مع مولد رقم عشوائي آمن مشفر. إذا كان يتم إنشاء اثنين UUIDs في تسلسل سريع بما فيه الكفاية أن الطابع الزمني يطابق UUID السابق، يتزايد الطابع الزمني بمقدار 1. التصادم لا ينبغي أن يحدث ما لم يحدث أحد الخيارات التالية: تم تزييف عنوان MAC. آلة واحدة تشغيل اثنين من التطبيقات المختلفة لتوليد UUID تنتج UUIDs في نفس اللحظة بالضبط. يتم إعطاء جهازين بدون بطاقة الشبكة أو دون وصول مستوى المستخدم إلى عنوان MAC نفس تسلسل عقدة عشوائي، وتوليد UUIDs في نفس اللحظة بالضبط. ونحن نفد من وحدات البايت لتمثيل الطابع الزمني والانتقال الى نقطة الصفر.

واقعيا، فإن أيا من هذه الأحداث تحدث عن طريق الصدفة في الفضاء ID طلب واحد ل. إلا إذا كنت تقبل معرفات على، مثلا، على نطاق واسع الإنترنت، أو مع بيئة غير موثوق بها حيث قد تكون قادرة على فعل شيء سيئ في حالة وقوع تصادم ID الأفراد الخبيثة، انها مجرد لا شيء يجب أن تقلق. من المهم جدا أن نفهم أنه إذا كنت يحدث لتوليد نفس الإصدار 4 UUID كما أفعل أنا، في معظم الحالات، لا يهم. لقد ولدت ID في الفضاء ID مختلف تماما من يدكم. طلبي لن نعرف أبدا عن التصادم حتى لا يهم الاصطدام. بصراحة، في مكان واحد دون تطبيق الجهات الخبيثة، وانقراض جميع أشكال الحياة على الأرض تحدث طويلة قبل لديك الاصطدام، حتى على UUID الإصدار 4، حتى لو كنت توليد عدد غير قليل من UUIDs في الثانية الواحدة.

وكذلك 2 ^ 64 * 16 256 إكسا بايت. كما هو الحال في، وكنت بحاجة لتخزين 256 إكسا بايت بقيمة معرفات قبل كانت لديه فرصة 50٪ من اصطدام ID في الفضاء تطبيق واحد.

نصائح أخرى

الشيء الذي تشتريه لك UUID والذي يصعب جدًا القيام به بخلاف ذلك هو الحصول على معرف فريد دون الحاجة إلى التشاور أو التنسيق مع السلطة المركزية.المشكلة العامة المتمثلة في القدرة على الحصول على شيء كهذا دون وجود نوع من البنية التحتية المُدارة هي المشكلة التي تحلها UUIDs.

لقد قرأت أنه وفقًا لمفارقة عيد الميلاد، فإن فرصة حدوث تصادم UUID هي 50% بمجرد إنشاء 2^64 UUID.الآن 2^64 هو رقم كبير جدًا، لكن احتمال الاصطدام بنسبة 50% يبدو محفوفًا بالمخاطر للغاية (على سبيل المثال، كم عدد UUIDs التي يجب أن تكون موجودة قبل أن تكون هناك فرصة بنسبة 5% للاصطدام - حتى هذا يبدو احتمالًا كبيرًا جدًا). .

المشكلة في هذا التحليل ذات شقين:

  1. UUIDs ليست عشوائية تمامًا - هناك مكونات رئيسية لـ UUID تعتمد على الوقت و/أو الموقع.لذا، للحصول على أي فرصة حقيقية للتصادم، يجب إنشاء UUID المتصادمة في نفس الوقت بالضبط من مولدات UUID مختلفة.أود أن أقول أنه على الرغم من أن هناك فرصة معقولة لإنشاء العديد من معرفات UUID في نفس الوقت، إلا أن هناك ما يكفي من المواد اللزجة الأخرى (بما في ذلك معلومات الموقع أو البتات العشوائية) لجعل احتمال حدوث تصادم بين هذه المجموعة الصغيرة جدًا من معرفات UUID مستحيلًا تقريبًا .

  2. بالمعنى الدقيق للكلمة، تحتاج UUIDs فقط إلى أن تكون فريدة من بين مجموعة UUIDs الأخرى التي يمكن مقارنتها بها.إذا كنت تقوم بإنشاء UUID لاستخدامه كمفتاح قاعدة بيانات، فلا يهم إذا كان نفس UUID يستخدم في مكان آخر في عالم بديل شرير لتحديد واجهة COM.تمامًا كما أنه لن يسبب أي ارتباك إذا كان هناك شخص (أو شيء) آخر يُدعى "مايكل بور" على Alpha-Centauri.

وكل شيء له غير الصفر فرصة للفشل. وأود أن التركيز على أكثر من المحتمل أن تحدث مشاكل (أي شيء تقريبا يمكن ان يخطر لك) من اصطدام UUIDs

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

وUUID / GUID و، نسبيا، وهي طريقة سريعة وسهلة حسابيا لتوليد ID التي يمكن أن تكون <م> معقول يفترض أن تكون فريدة من نوعها عالميا. وهذا أمر مهم جدا في العديد من الأنظمة التي تحتاج إلى دمج البيانات من أنظمة لا علاقة سابقا. على سبيل المثال: إذا كان لديك نظام إدارة المحتوى الذي يمتد على منصتين مختلفة، ولكن في مرحلة ما في حاجة لاستيراد المحتوى من نظام واحد إلى الآخر. كنت لا تريد معرفات لتغيير، لذلك لا تزال المراجع الخاصة بك بين البيانات من نظام وسليمة، ولكن كنت لا تريد أي اصطدام مع البيانات التي تم إنشاؤها في نظام B. A UUID يحل هذه.

وانها ليست ابدا الضروري للغاية لإنشاء UUID. غير أنه ملائم لدينا معيار حيث <م> متواجد حاليا يمكن للمستخدمين كل تولد المفتاح إلى شيء مع احتمال ضعيف جدا من الاصطدام.

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

وسيكون من السهل على الانترنت للمستخدمين لتوليد مفاتيح فريدة من نوعها لشيء دون النفقات العامة أو احتمال تصادم، ولكن هذا ليس هو ما هي UUIDs ل.

وعلى أي حال، كلمة عن احتمال الاصطدام، والتي اتخذت من ويكيبيديا:

<اقتباس فقرة>   

لوضع هذه الأرقام في منظورها الصحيح، واحد خطر السنوي من التعرض للضرب   من يقدر نيزك لتكون فرصة واحدة في 17 مليار، أي ما يعادل   لاحتمالات خلق بضع عشرات التريليونات من UUIDs في السنة، و   وجود نسختين واحدة. وبعبارة أخرى، إلا بعد توليد 1000000000   UUIDs كل ثانية على مدى السنوات ال 100 المقبلة، واحتمال خلق   مجرد تكرار للمرء أن يكون حوالي 50٪.

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

هل تقلق بشأن ذلك؟

والمثال الكلاسيكي هو عند تكرار بين قاعدتي.

وDB (A) إدراج سجل مع 10 ID int و في نفس الوقت DB (B) بإنشاء سجل مع في 10. ID هذا الاصطدام.

ومع UUIDs هذا لن يحدث لأنها لن تطابق. (شبه المؤكد)

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

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

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

إذا كنت مجرد إلقاء نظرة على البدائل مثل لتطبيق قاعدة بيانات بسيطة، أن يكون الاستعلام عن قاعدة بيانات في كل مرة قبل إنشاء كائن جديد، وسوف تجد قريبا أن استخدام UUID يمكن أن تقلل بشكل فعال في تعقيد النظام الخاص بك. منح - إذا كنت تستخدم مفاتيح كثافة العمليات هي 32BIT والتي سوف تخزن في ربع UUID 128bit. منح - الخوارزميات الجيل UUID يستغرق أكثر قوة الحسابية من مجرد تزايد عدد. لكن من يهتم؟ النفقات العامة لإدارة "سلطة" لتعيين أرقام مميزة خلاف ذلك بسهولة تفوق ذلك عن طريق أوامر من حجم، اعتمادا على مساحة ID التفرد المقصود الخاص بك.

على UUID==تصميم كسول

أنا لا أتفق مع الأمر بشأن اختيار معاركك.إذا كان UUID المكرر مستحيلًا إحصائيًا وتم إثبات الرياضيات فلماذا القلق؟إن قضاء الوقت في التصميم حول نظام توليد N UUID الصغير الخاص بك أمر غير عملي، فهناك دائمًا عشرات الطرق الأخرى التي يمكنك من خلالها تحسين نظامك.

وأنا لا أحصل على كل ما يقال عن احتمال الاصطدام. لا يهمني حول الاصطدام. ما يهمني الأداء بالرغم من ذلك.

https://dba.stackexchange.com/a/119129/33649

<اقتباس فقرة>   

وUUIDs هي كارثة الأداء لجداول كبيرة جدا. (200K الصفوف هي   لا "كبيرة جدا".)

     

و# لديك 3 سيء حقا عندما SET CHARCTER هو UTF8 - CHAR (36)   تحتل 108 بايت!

     

وUUIDs (المعرفات الفريدة العمومية) هي جدا "عشوائية". استخدامها إما UNIQUE أو   المفتاح الأساسي على جداول كبيرة غير فعال جدا. وذلك لأن من   الحاجة إلى القفز حول الطاولة / مؤشر في كل مرة قمت بإدراج UUID جديد   أو الاختيار عن طريق UUID. عندما يكون الجدول / مؤشر كبير جدا لاحتوائه في ذاكرة التخزين المؤقت   (انظر innodb_buffer_pool_size، التي يجب أن تكون أصغر من ذاكرة الوصول العشوائي،   عادة 70٪)، قد لا يكون التخزين المؤقت UUID "التالي"، وبالتالي قرص بطيئة   نجاح. عندما يكون الجدول / المؤشر 20 مرة كبيرة مثل ذاكرة التخزين المؤقت، فقط 1/20   (5٪) من يتم مؤقتا الزيارات - أنت I / O-المنضم

.      

وهكذا، لا تستخدم إلا UUIDs إما

     

ولديك جداول "صغيرة"، أو كنت حقا في حاجة إليها لتوليد   لم أحسب هويات فريدة من أماكن مختلفة (ومن وسيلة أخرى   للقيام بذلك). أكثر على UUIDs: http://mysql.rjweb.org/doc.php/uuid (و   تشمل وظائف لتحويل بين القياسية UUIDs 36 شار و   BINARY (16)).

     

وجود كل من AUTO_INCREMENT UNIQUE وUUID UNIQUE في نفسه   الجدول هو مضيعة.

     

عند حدوث INSERT، لا بد من فحص جميع مفاتيح فريدة من نوعها / الابتدائية لل   التكرارات. إما مفتاح فريد كافية لمتطلبات ك InnoDB ل   وجود مفتاح أساسي. BINARY (16) (16 بايت) هو ضخمة نوعا ما (ل   حجة ضد يجعله PK)، ولكن ليس بهذا السوء. ضخامته   يهم عندما يكون لديك مفاتيح الثانوية. ك InnoDB المسامير بصمت PK   إلى نهاية كل مفتاح الثانوي. الدرس الرئيسي هنا هو ل   تقليل عدد مفاتيح الثانوية، وخاصة بالنسبة كبيرة جدا   الجداول. لالمقارنة: INT غير الموقعة 4 بايت مع مجموعة من 0..4   مليار. BIGINT هو 8 بايت.

وفي وظيفتي الماضي، كنا نحصل الكائنات من الأطراف الثالثة التي تم تحديدها بشكل فريد مع UUID. أضع في UUID-> صحيح طويل طاولة البحث واستخدام عدد صحيح طويل كما المفاتيح الأساسية بلدي لأنه كان وسيلة أسرع بهذه الطريقة.

وباستخدام خوارزمية النسخة 1 يبدو أنه هو الاصطدام من المستحيل في ظل القيود التي يتم إنشاؤها أقل من 10 UUIDs في ميلي ثانية واحدة من نفس عنوان MAC

<اقتباس فقرة>   

ومن الناحية النظرية، الأصلي (الإصدار 1)   كان مخطط جيل لUUIDs ل   سلسلة النسخة UUID مع   عنوان MAC للكمبيوتر الذي هو   توليد UUID، ومع   عدد من فترات 100 نانو ثانية   منذ اعتماد الميلادي   التقويم في الغرب. في الممارسة العملية،   الخوارزمية الفعلية أكثر تعقيدا.   وقد انتقد هذا المخطط في   أنه ليس بما فيه الكفاية "مبهمة".   أنه يكشف عن كل من هوية   الكمبيوتر التي ولدت UUID و   في الوقت الذي فعلت ذلك.

وشخص يصحح لي إذا كنت أسيء تفسيرها كيف يعمل

لهؤلاء قائلا ان UUIDs هي تصميم سيء لأنهم <م> يمكن (في بعض احتمال صغير يبعث على السخرية) تصطدم، في حين ولدت DB بك مفاتيح لن ... أنت تعرف فرصة للخطأ البشري مما تسبب في تصادم على DB الخاص بك إنشاء مفاتيح بسبب بعض الحاجة، forseen الامم المتحدة هو FAR FAR أعلى بكثير من فرصة UUID4 الاصطدام. نحن <م> معرفة أنه إذا تم صوغه ديسيبل انها ستبدأ هويات في 1 مرة أخرى، وكم منا قد اضطر إلى إعادة جدول عندما كنا على يقين من أننا لن تحتاج أي وقت مضى ل؟ كنت وضعت أموالي على الامان UUID عندما يبدأ الاشياء تسير بشكل خاطئ مع المجهولة غير معروفة في أي يوم.

وبصرف النظر عن الحالات التي لديك لاستخدام API شخص آخر أن يطالب UUID، بالطبع هناك دائما حل آخر. ولكن تلك البدائل حل <م> جميع المشاكل التي UUIDs تفعل؟ سوف ينتهي بك الأمر إضافة المزيد من طبقات من الخارقة، كل من أجل حل مشكلة مختلفة، عندما يمكن أن تحل كل منهم في وقت واحد؟

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

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

وو"واضح" الحل الآخر هو السلطة المركزية أن يسلم بها كتل من الأرقام الفريدة مقدما، التي هي في جوهرها ما لا UUID V1 باستخدام عنوان MAC للجهاز توليد (عبر IEEE OUI). لكن تكرار عناوين MAC لا يحدث لأن كل سلطة مركزية مسامير يصل في نهاية المطاف، وذلك في الواقع هذا هو الأرجح بكثير من اصطدام UUID V4. عفوا.

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

ومن الممكن المشكلة ليست كبيرة بما يكفي لحاجة ما تقدمه UUIDs، وفي هذه الحالة، لا تتردد في استخدام شيء آخر. ولكن إذا ينمو مشكلتك بشكل غير متوقع (ومعظم تفعل)، فسوف ينتهي التحويل في وقت لاحق - وركلة نفسك لعدم استخدامها في المقام الأول. لماذا تصميم لفشل عندما يكون مثلما من السهل تصميم للنجاح بدلا من ذلك؟

وUUIDs تجسد كل الممارسات السيئة الترميز المرتبطة المتغيرات العالمية، إلا سوءا، لأنها متغيرات superglobal التي يمكن توزيعها على قطع مختلفة من عدة.

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

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