0

I have a system which communicate to external system via webservices in which we used to send random nos as msg id and same is getting stored as a primary key of table in our database. Problem here is since we have approx 80-90 k call on daily basis i have seen so many exceptions saying that duplicate primary key. I am generating random nos in java. How can i be sure that whatever random number i will generate will not be duplicated.

below is code for the generating random nos:

private static int getRandomNumberInRange(int min, int max) {

    if (min >= max) {
        throw new IllegalArgumentException("max must be greater than min");
    }

    Random r = new Random();
    return r.nextInt((max - min) + 1) + min;
}
14
  • 4
    You cannot. Using a random number for a PK is a bad idea. create a UUID instead and use that as the key. Commented Sep 25, 2017 at 18:30
  • 2
    Use a DB sequence or auto increment column if the DB supports it. Commented Sep 25, 2017 at 18:31
  • 3
    There's really two issues here: 1. Random values cannot be guaranteed unique. If it could, then it wouldn't be random. 2. Why are you trying to use a random number as a primary key? Why not a sequence, so that it is guaranteed unique on insert? Commented Sep 25, 2017 at 18:32
  • 1
    @VinaySharma You are right; UUIDs will eventually generate duplicates over time. This is called the Birthday Paradox. However, if you do the math, it is very, very, VERY unlikely that your system would ever generate a single random UUID more than once. You hit about a 0.0000000001% chance of a duplicate after generating over 100-trillion UUIDs. Commented Sep 25, 2017 at 18:37
  • 2
    @VinaySharma sir u can use a UUID instead of Random number in java. UUID.fromString("38400000-8cf0-11bd-b23e-10b96e4ef00d"); Commented Sep 28, 2017 at 12:44

2 Answers 2

1

There's nothing wrong with using a random number as a primary key. You just need to make sure that numbers are chosen from a range large enough to make the chance of picking a number more than once is virtually zero.

If you generate 100k identifiers per day for 30 years, that's about 1 billion identifiers. So, using a 100-bit number will make a collision virtually impossible over that time. 13 bytes, or maybe 12 if you feel lucky.

I define "virtually zero" as 2-40. There's not much point in defining it as less than 2-50, because things like RAM and hard drives are more likely than that to suffer undetected errors. When you have to satisfy a uniqueness constraint, estimates involving a 50% chance of collision are useless.

There is nothing magic about UUIDs. They are just 122-bit numbers with a verbose encoding. They will work, but they are overkill for this application.

Sign up to request clarification or add additional context in comments.

4 Comments

And I got -2 for the same idea.
@Lothar let me see you defending your principle
@Yahya I don't understand your comments.
Sorry erickson , your approach is 100% correct, and plus one from me. tho I answered something similar before yours and deleted it because immediately got -2 downvotes , one of them is from @Lothar who claims this is incorrect approach.
0

You need to use a large random number, and a good source of randomness. int is not large enough, and you're restricting your range to less than that with your min and max.

The rule of thumb is that you should expect a 50% chance of collision for every 2n/2 numbers, where n is the number of bits in your random number.

The Random class in java.util isn't a good source for truely random numbers (among other problems, it uses a 48 bit seed). You should use SecureRandom, and at least a long. You should also construct it outside your method to avoid the overhead of initialisation.

As others have suggested, a UUID would solve your problem.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.