【问题标题】:Approach for generating unique, composite, consecutive numbers with several number ranges生成具有多个数字范围的唯一、复合、连续数字的方法
【发布时间】:2018-07-18 23:43:42
【问题描述】:

使用 PostgreSQL 作为 RDBMS(通过普通 JDBC 使用)的 Java 应用程序使用复合的连续数字,例如 [CustomerNumber]-[Year]-[ConsecutiveNumber],其中 [ConsecutiveNumber] 再次以 1 开始,每个新客户和每个新年都使用 1。格式化为字符串,数字看起来像10123-2018-0001

DB 表中有一个 UNIQUE 约束,以确保客户编号、年份和连续编号的每个组合只能存在一次。

下一个要分配的空闲号码被确定为 (Select Max(ConsecutiveNumber) From XYZ Where CustomerNumber=? And Year=?)+1。这只适用于锁定/同步以及一次只有一个服务器软件实例的事实(没有水平可扩展性,即有机会在前面有负载平衡器的多台服务器上运行应用程序)。

当然可以忽略同步,但是由于违反唯一约束,很多事务/提交都会失败。

对于生成此类复合唯一数字,您建议采用什么方法? 由于可以有无限的客户编号和年份,因此为每个客户编号/年份组合创建专用的 DB SEQUENCE 似乎是不可行的。

我想使用一个专门的Connection/事务来插入一个新生成的数字,以减少它已经被另一个线程/并发事务中的概率。但是,如果实际的业务交易由于任何原因没有提交,这将导致不一致的数据(“幽灵数字”)。

【问题讨论】:

  • consecutiveNumber增加的条件是什么?
  • @BShaps 增加 1。假设有 10123-2017-000110123-2017-000210123-2018-0001。那么客户10123 在年份2018 的下一个免费号码是10123-2018-0002。 (虽然已经有10123-2017-0002 但那是不同的年份。) - 不确定我的评论是否回答了你的问题。 :)

标签: java database postgresql sequence


【解决方案1】:

PostgreSQL 具有“自动增量”类型SERIAL 来生成新密钥。 这将是插入新记录的明显方式,然后getGeneratedKeys() 会询问这些键。

然而,在商业中,经常需要在一年内进行这样的连续编号。

通常会看到一个组合:一个生成的主键(用户永远不会看到)和一个具有唯一性约束的自然键(可能不是)。这允许在订单发布(打印、通过电子邮件发送)时添加自然键。此外,它还允许维修。

正如您对自己的评估,“顺序密钥生成器”并非微不足道。但是您可以将自然键拆分为 compound 键:年份、序列号。 这将简化 SQL 的使用。

我希望另一个答案会给出一个更有趣的实用解决方案。

【讨论】:

    猜你喜欢
    • 2021-06-04
    • 1970-01-01
    • 2013-06-29
    • 1970-01-01
    • 2013-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    相关资源
    最近更新 更多