مولّد UUID v7
بنية UUID v7: الطابع الزمني المضمن والعشوائية
UUID v7 هو معرّف فريد عالميًا من الجيل السابع، طوله 36 حرفًا، مبني على 128 بت. تبدأ أول 48 بت بتمثيل الطابع الزمني لميلي ثانية يونكس (Unix millisecond timestamp)، ثم تتبعها 74 بت من العشوائية القوية، مع 6 بت مخصصة للنسخة والاختلاف (version and variant bits). هذا التصميم يجعله فريدًا من نوعه: أول حرفين من السلسلة النصية يعكسان الوقت الذي أُنشئ فيه المعرف. على سبيل المثال، إذا أنشأنا UUID v7 في اللحظة التي تكتب فيها هذه الكلمات، فسيبدأ بـ "018f" تقريبًا. العشوائية اللاحقة تضمن أنه حتى لو أنشئت آلاف المعرفات في نفس الميلي ثانية، فاحتمال التصادم ضئيل جدًا – من الناحية العملية معدوم.
هذه البنية تختلف جذريًا عن UUID v4، الذي يعتمد كليًا على العشوائية (122 بت عشوائي) دون أي طابع زمني. UUID v7 يمزج بين أفضل ما في العالمين: يمكن ترتيبه زمنيًا ويبقى غير قابل للتخمين.
لماذا الترتيب الزمني ضروري لفهرسة قواعد البيانات
عند استخدام UUID v4 كمفتاح أساسي في قاعدة بيانات تستخدم شجرة B (B-tree) مثل PostgreSQL أو MySQL، فإن العشوائية الكاملة تتسبب في كتابة البيانات في صفحات عشوائية عبر القرص. يؤدي هذا إلى تجزؤ شديد في الفهرس (index fragmentation)، وإبطاء عمليات الإدراج، وزيادة عدد مرات إعادة تنظيم الصفحات. أما UUID v7، فبسبب احتوائه على طابع زمني في البداية، فإن المعرفات الجديدة تُدرج بالقرب من نهاية الفهرس، مما يحسن "الترجيح المحلي" (index locality) ويقلل التجزؤ. هذا يشبه عمل المفاتيح المتزايدة ذاتيًا (auto-increment integers)، لكن مع ميزة إضافية: يمكنك إنشاء المعرفات في تطبيقات موزعة دون الحاجة إلى مخدم مركزي لتوليد الأرقام المتسلسلة.
الفرق واضح: في اختبارات الأداء، يمكن أن يكون أداء الإدراج باستخدام UUID v7 أسرع بنسبة تصل إلى 50% من UUID v4 في قواعد البيانات الكبيرة، لأن الكتابة تحدث في نطاق ضيق من الكتل بدلاً من توزيعها عشوائيًا.
حدود الترتيب داخل نفس الميلي ثانية: المقايضة الحتمية
لا يضمن UUID v7 ترتيبًا صارمًا للمعرفات المولّدة في نفس الميلي ثانية. على سبيل المثال، إذا أنشأت 100 معرف في نفس اللحظة (بدقة ميلي ثانية واحدة)، فقد يظهر المعرف "أ" قبل المعرف "ب" بالصدفة في القائمة، لكن هذا لا يعني أن "أ" أُنشئ قبل "ب". السبب أن الجزء الزمني يتطابق تمامًا، والبتات العشوائية التالية لا تحمل أي معلومات زمنية أدق. هذه ميزة وليست عيبًا: فهي تسمح بتوليد معرفات متعددة بالتوازي دون قفل (locking)، وهو أمر حاسم في الأنظمة الموزعة عالية الإنتاجية. لو أردنا ترتيبًا دقيقًا داخل الميلي ثانية نفسها، لكان علينا إضافة عداد متسلسل (monotonic counter) أو وقت بدقة ميكروثانية، مما يضيف تعقيدًا أو يقلل قابلية التوسع.
البديل الوحيد للحصول على ترتيب دقيق مع الحفاظ على العشوائية هو استخدام ULID، الذي يعتمد على طابع زمني بدقة ميلي ثانية ثم عداد عشوائي مضمون الترتيب داخل نفس الميلي ثانية، لكنه يتطلب حالة (state) مشتركة. UUID v7 يفضل البساطة والتوزع.
التوليد المحلي في المتصفح: الخصوصية والسرعة
الأداة التي تصفها هذه الصفحة تعمل بالكامل داخل متصفح المستخدم. لا يُرسل أي شيء إلى خوادم الموقع (BroBroGo). تستخدم JavaScript دالة crypto.getRandomValues() القياسية في المتصفحات الحديثة، والتي توفر عشوائية قوية مشفرة (cryptographically strong). هذا يعني أن المعرفات تُنشأ فورًا، دون تأخير شبكة، وبدون أي خطر من تسرب البيانات إلى طرف ثالث. يمكن للمطورين الواثقين استخدام هذه الأداة لتوليد معرفات لقواعد بياناتهم المحلية أو أثناء التطوير دون قلق.
بالإضافة إلى ذلك، كل تغيير في الخيارات (العدد، حالة الأحرف، الواصلات) يعيد التوليد فوريًا. لا يوجد زر "إنشاء" منفصل؛ التفاعل مباشر.
خيارات التنسيق: الأحرف الكبيرة والواصلات
توفر الصفحة مفتاحين لتخصيص المخرجات:
- الرفع (Uppercase): عند تفعيله، تُكتب الأحرف السداسية العشرية (a–f) بالأحرف الكبيرة (A–F). ليس لذلك أي تأثير على القيمة الثنائية للمعرف، لكن بعض الأنظمة (مثل Windows) تفضل الأحرف الكبيرة في المعرفات لعرض أكثر وضوحًا.
- تضمين الواصلات (Include hyphens): المعيار الرسمي لـ UUID يتطلب 4 واصلات تفصل الأجزاء (8-4-4-4-12). لكن بعض التطبيقات (مثل أسماء الملفات أو المعرفات في URL) تستفيد من إزالة الواصلات لتوفير 4 أحرف. معًا، يمكنك الحصول على أي من التنسيقات التالية:
| الواصلات | الأحرف الكبيرة | مثال |
|---|---|---|
| نعم | لا | 018f0a1b-2c3d-4e5f-6789-0a1b2c3d4e5f |
| نعم | نعم | 018F0A1B-2C3D-4E5F-6789-0A1B2C3D4E5F |
| لا | لا | 018f0a1b2c3d4e5f67890a1b2c3d4e5f |
| لا | نعم | 018F0A1B2C3D4E5F67890A1B2C3D4E5F |
اختر ما يناسب نظامك. لا تغيير في القيمة الأساسية (128 بت) عند تغيير هذه الخيارات.
من يحتاج هذه الأداة؟
- مطورو الأنظمة الموزعة الذين يحتاجون مفاتيح أساسية قابلة للترتيب زمنيًا دون اعتماد على مخدم مركزي.
- مسؤولو قواعد البيانات الذين يعانون من تجزؤ فهارس UUID v4 ويريدون تحسين أداء الإدراج في جداول ضخمة.
- مهندسو الأمن الذين يطلبون معرفات غير قابلة للتخمين (بفضل العشوائية القوية) مع إمكانية تتبع وقت الإنشاء تقريبًا.
- كل من ينتقل من UUID v4 إلى تنسيق زمني لتقليل مشاكل الإدراج في B-tree.
الأسئلة الشائعة (FAQ)
هل UUID v7 آمن من الناحية التشفيرية؟
نعم، الجزء العشوائي (74 بت) يولّد باستخدام crypto.getRandomValues() وهو مناسب للتطبيقات التي تتطلب عدم قابلية التخمين، مثل الرموز المميزة (tokens) ومعرفات الجلسات.
كيف يختلف UUID v7 عن ULID؟
كلاهما يعتمد على طابع زمني. ULID أطول قليلاً (26 حرفًا باستخدام ترميز base32)، بينما UUID v7 محصور في التمثيل السداسي العشري (36 حرفًا). الفرق الرئيسي: ULID يضمن ترتيبًا صارمًا داخل نفس الميلي ثانية عبر عداد، بينما UUID v7 لا يضمن ذلك.
هل يمكنني استخدام UUID v7 كمفتاح أساسي في PostgreSQL؟
نعم، يدعم PostgreSQL نوع uuid ويقبل UUID v7 دون مشكلة. يمكنك إنشاء عمود id uuid PRIMARY KEY DEFAULT gen_random_uuid()، لكن التجربة تظهر أن استخدام UUID v7 يُحسن أداء الإدراج مقارنة بالعشوائي.
ماذا يحدث إذا غيرت خيارات العدد أو حالة الأحرف بعد توليد المعرفات؟
كما ذكرنا، كل تغيير يعيد التوليد فورًا. لا تُحفظ أي حالة سابقة. إذا كنت تريد الاحتفاظ بمجموعة معينة، انسخها قبل تعديل الخيارات.
لماذا لا يضمن UUID v7 الترتيب داخل نفس الميلي ثانية؟
لأن التصميم اختار العشوائية والتوزع بدلاً من إضافة عداد متسلسل. هذا يبسط التوليد في بيئات متوازية ويجنب الحاجة إلى حالة مشتركة، وهو الخيار الأمثل لمعظم أنظمة الإنتاج.
هل يمكنني توليد أكثر من 100 معرف في المرة الواحدة؟
الأداة محددة بـ 1–100 لكل عملية توليد. إذا احتجت المزيد، كرر التوليد عدة مرات، أو ادمج القوائم المنسوخة يدويًا. لا يوجد حد نظري، لكن واجهة المستخدم توازن بين الوضوح وسهولة النسخ.
ملاحظة: القيم المولّدة من هذه الصفحة مناسبة للاستخدام في أي نظام يدعم UUID القياسي. احتفظ بنسخة احتياطية من معرفاتك المهمة.