如何在SQL中为主键生成唯一的随机数

时间:2018-07-04 06:55:07

标签: sql h2

我正在处理一个需求,其中我需要生成一个至少有10位数字的唯一(不可重复)和随机数(不可预测)。我尝试了 SELECT FLOOR(RAND()* 9999999) ..,但是不能保证唯一性。 每月大约插入2万个值。

我还想为插入的每个条目增加表的int列(number_of_hits)...我正在使用Spring Boot将值插入表中。 在创建表时尝试过 number_of_hits int AUTO_INCREMENT ,但后来知道这仅适用于主键。 预先谢谢。!

4 个答案:

答案 0 :(得分:2)

最简单的解决方案是使用UUID datatype (which can be populated automatically),并在需要时将其转换为INT。

UUID是128位整数,can be converted to BigInteger;通常以十六进制值形式存储,该值看起来可能是字符串。

答案 1 :(得分:0)

使用newid()函数。这将创建一个类型为uniqueidentifier的唯一值。

NEWID()
SELECT NEWID()

您可以这样使用。

INSERT INTO mytable (column1) VALUES (NEWID())

答案 2 :(得分:0)

我已经采用了以下解决方案,它也可以处理数百万条记录。.谢谢大家的回答。

      Calendar cal = Calendar.getInstance();
      long currentTime = cal.getTimeInMillis();
      long Max = 9999999999999L;
      long Min = 1000000000000L;
    long range = Math.abs((long) (Math.random() * (Max - Min)) + Min);
    long id = Math.addExact(currentTime, range);
    String uniqueID = createUniqueID(id);
    boolean isRepeated = urlShortenerRepository.existsByShortUrlKey(uniqueID);
    while (isRepeated) {
        range = Math.abs((long) (Math.random() * (Max - Min)) + Min);
        id = Math.addExact(currentTime, range);
        uniqueID = createUniqueID(id);
        isRepeated = urlShortenerRepository.existsByShortUrlKey(uniqueID);
    }

答案 3 :(得分:0)

由于您已选择使用Java代码生成唯一标识符,因此我想说,您应该生成一个将“唯一”部分和“随机”部分结合在一起的unique identifier。请注意,您的current answer并不完全满足“不可预测”的要求,因为它使用了Math.random(),不一定是“不可预测”的RNG。

  • “唯一”部分可以是单调递增的计数器,也可以是用全周期linear congruential generator生成的数字(在重复之前,该周期将在其周期内伪随机地遍历所有可能的值)。我不建议单独使用时间戳,因为存在快速连续生成相同时间戳的风险。
  • “随机”部分只是一个由密码随机数生成器生成的随机数(对于Java为java.security.SecureRandom;使用“ DRBG”实现而不是“ SHA1PRNG”)(如果可用)。通常,随机部分越长,可预测性就越差。

您当前的代码在正确的轨道上,但是您应该将随机ID的两个部分(例如它们是字符串)串联起来,而不是在当前时间上添加任意偏移量(例如,如果cal.getTimeInMillis()返回大于Min的数字?)。