سؤال

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

طباعة جيدة:

  1. أنا لا أستخدم نظام RDBMS، لذلك ليس لدي أي مولدات تسلسلية رائعة (مثل تلك التي توفرها Oracle)
  2. أريد أن يكون سريعًا، ويفضل أن يكون كله في الذاكرة - أفضل ألا أضطر إلى فتح ملف وزيادة بعض القيمة
  3. يجب أن يكون آمنًا (أتوقع أن JVM واحد فقط في كل مرة سيحتاج إلى إنشاء معرفات)
  4. يجب أن يكون هناك اتساق عبر عمليات إنشاء JVM.إذا تم إيقاف تشغيل الخادم وتشغيله، فلا ينبغي لمولد المعرفات إعادة إنشاء نفس المعرفات التي أنشأها في عمليات المثيلات السابقة (أو على الأقل يجب أن تكون الفرصة ضئيلة للغاية - أتوقع عدة ملايين من الموارد الموجودة)
  5. لقد رأيت الأمثلة في مقالة نمط المعرف الفريد لـ EJB.لن تعمل معي (أفضل عدم الاعتماد فقط على System.currentTimeMillis() لأننا سنحتفظ بموارد متعددة في كل مللي ثانية).
  6. لقد ألقيت نظرة على الإجابات المقترحة في هذا السؤال.ما يقلقني بشأنهم هو، ما هي فرصة حصولي على بطاقة هوية مكررة مع مرور الوقت؟أنا مفتون باقتراح الاستخدام java.util.UUID ل UUID, ، ولكن مرة أخرى، يجب أن تكون فرص التكرار صغيرة للغاية.
  7. أنا أستخدم JDK6
هل كانت مفيدة؟

المحلول

من المؤكد أن UUIDs "جيدة بما فيه الكفاية".هناك 340,282,366,920,938,463,463,374,607,431,770,000,000 UUID متاحة.

http://www.wilybeagle.com/guid_store/guid_explain.htm

"لوضع هذه الأرقام في نصابها الصحيح، يقدر الخطر السنوي لإصابة الشخص بنيزك باحتمال واحد في 17 مليار، وهذا يعني أن الاحتمال يبلغ حوالي 0.00000000006 (6 × 10−11)، أي ما يعادل احتمالات إنشاء عدد قليل من النيازك. عشرات التريليونات من UUIDs في عام واحد ولها نسخة واحدة مكررة.بمعنى آخر، فقط بعد إنشاء مليار UUID كل ثانية على مدار المائة عام القادمة، سيكون احتمال إنشاء نسخة مكررة واحدة فقط حوالي 50%.احتمالية وجود نسخة واحدة ستكون حوالي 50% إذا كان كل شخص على وجه الأرض يمتلك 600 مليون UUID.

http://en.wikipedia.org/wiki/Universally_Unique_Identifier

نصائح أخرى

public class UniqueID {
    private static long startTime = System.currentTimeMillis();
    private static long id;

    public static synchronized String getUniqueID() {
        return "id." + startTime + "." + id++;
    }
}

إذا كان يجب أن يكون فريدًا لكل جهاز كمبيوتر:ربما يمكنك استخدامها (System.currentTimeMillis() << 4) | (staticCounter++ & 15) أو شيء من هذا القبيل.

سيسمح لك ذلك بإنشاء 16 لكل مللي ثانية.إذا كنت بحاجة إلى المزيد، قم بالتحويل بمقدار 5 وسيكون ذلك بـ 31...

إذا كان من الضروري أن يكون فريدًا عبر أجهزة كمبيوتر متعددة، فيجب عليك أيضًا دمج عنوان MAC الخاص ببطاقة الشبكة الأساسية لديك.

يحرر:للتوضيح

private static int staticCounter=0;
private final int nBits=4;
public long getUnique() {
    return (currentTimeMillis() << nBits) | (staticCounter++ & 2^nBits-1);
}

وقم بتغيير nBits إلى الجذر التربيعي لأكبر رقم يجب أن تحتاج إلى إنشائه لكل مللي ثانية.

سوف يتدحرج في النهاية.ربما 20 عامًا أو شيء من هذا القبيل مع nBits عند 4.

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

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

إنه يعمل بشكل جيد وسريع بشكل لا يصدق (بمجرد تهيئة messageDigest لأول مرة).

لماذا لا تفعل مثل هذا

String id = Long.toString(System.currentTimeMillis()) + 
    (new Random()).nextInt(1000) + 
    (new Random()).nextInt(1000);

إذا كنت تريد استخدام تطبيق أقصر وأسرع، فقم بإلقاء نظرة على Java UUID:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/main/java/org/spf4j/concurrent/UIDGenerator.java

راجع خيارات التنفيذ والقيود في ملف javadoc.

فيما يلي اختبار الوحدة حول كيفية الاستخدام:

https://code.google.com/p/spf4j/source/browse/trunk/spf4j-core/src/test/java/org/spf4j/concurrent/UIDGeneratorTest.java

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