【问题标题】:Generating unique reference number生成唯一的参考号
【发布时间】:2012-07-18 23:41:39
【问题描述】:

技术栈:Java 1.6、JPA(Hibernate 3)、Spring 3、Oracle 11g

我正在开展一个项目,其中一项要求是向客户返还“ReferenceNumber”。

一种选择是返回行 ID,但要使其正常工作,它不能是连续的。否则,您可以猜测下一个数字等。

我可以在 Java 中生成一个数字并将其存储在单独的列中,但我会确保没有冲突。

有办法在数据库中生成这样的数字,但不确定它是否能保证唯一性。

从数据库的角度来看,这种需求是否存在最佳实践?

更新 1

当前我在 Java 中使用以下代码生成数字:

    private static SecureRandom random = new SecureRandom();

    public static BigInteger getNew() {
        return new BigInteger(60, random);
    }

    public static BigInteger getNew(int numBits) {
        return new BigInteger(numBits, random);
    }

更新 2:要求

允许序号将允许:

  1. 客户猜下一个数字。
  2. 找出两个数字之间有多少个数字(订单)。等等

这个引用最好是一个数字,但是说一个三个字母的前缀后跟数字也可以。

【问题讨论】:

  • 猜下一个数字有什么问题?安全要求是什么?
  • @stark 有一个很好的观点。你的安全不应该简单地基于参考号的混淆。应该始终对用户和记录进行访问检查。
  • ReferenceNumber 需要是数字吗?可以改为字母数字 GUID 吗?
  • 我更愿意为我的客户提供比 GUID 更小的参考 ID。
  • @RichardClayton - 如果目标是给人类一个他们必须写下并输入的数字,我同意。如果目标是为某些计算机提供可用于后续调用的密钥,则 GUID 可能是合理的。

标签: java database oracle hibernate primary-key


【解决方案1】:

如果您的表有一个序列生成的主键(例如 customer_id),那么您可以反转数字,然后将其转换为八进制表示。因此它看起来仍然像一个十进制数,但它绝对不再是连续的并且很难猜出任何范围。

如果您能找到一种方法来处理原始值中的尾随零(因为它们会成为反转数字中的前导零,因此在转换过程中将被“丢弃”),则该过程甚至是可逆的。

【讨论】:

    【解决方案2】:

    用客户缩写或名称缩写或其他东西(或创建客户时分配的 3 个字母,检查唯一性)作为数字前缀,然后只存储一个值,然后为该客户按顺序递增?这样他们就无法知道系统其余部分中的订单号是多少,但他们可以自己知道,这并不重要,因为他们知道他们已经下了多少订单。

    【讨论】:

      【解决方案3】:

      为什么不采用几个相关字段的 SHA1 或 MD5 哈希(比如用户名和记录创建时间等)?在许多方面,如果该策略众所周知,您的数据库外部服务将能够重新创建参考编号,而无需查询数据库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多