使用hilo高低位算法-生成编号

合理设计订单编号与生成策略
本文探讨了在设计订单编号时不合理的方法,并提出了一种使用表管理数字主键的合理解决方案,通过自定义优化器生成高效且有序的订单编号。

通常订单编号、产品编号、付款编号等编号,都是由数字构成,有得会加一些前缀后缀,例如淘宝订单号。

下面说一下几点不合理的编号设计。

  1. 使用数字型的自增长、序列。这用来表示唯一性没问题,但是当我们遇到像订单编号这种,需要一定长度不太合适。

  2. 编号需要一定长度,可能你会想到uuid。uuid生成的包含字符,无序、无意义而且也比较长,不符合我们的写记习惯,所以uuid做编号也是不合理的。

  3. 使用时间戳来当编号,在并发的情况下精确到毫秒也有可能发生唯一性问题

  4. 使用随机数加前后缀当编号,很多语言的随机数都是伪随机,例如用java每次都new Random(),并发的情况下有可能取出一样的数字,就算不并发,谁能保证不会随机到之前生成过的数字?


合理的做法是用表来管理数字主键,每次取出来拼接前缀或后缀来当编号,然后+1,就像oracle的序列一样,因为有些数据库没有序列,所以通常为了统一使用表来管理。

private class HiloOptimizer {

        private String prefix;
        private int maxLo;
        private int lo;            
        private long hi;        
        private long lastValue;

        public HiloOptimizer(String prefix, int maxLo) {
            this.prefix = prefix != null ? prefix.replace("{", "${") : "";
            this.maxLo = maxLo;            //最大低位
            this.lo = maxLo + 1;           //最低初始位
        }

        public synchronized String generate() {
            if (lo > maxLo) {                    //当低位超过最大高位
                lastValue = getLastValue();  //表示hi位的进位次数,从数据库id管理表获取
                lo = lastValue == 0 ? 1 : 0;     //低位归0
                hi = lastValue * (maxLo + 1);    //高位进位
            }
            return String.valueOf(hi + lo++);    //低位最后自增lo++
        }
    }

若maxLo设置为99,按照hi的每次进位划分,产生的id形式是:

0~99,100~199,200~299,300~399……依此类推,每个阶段99+1个


转载于:https://my.oschina.net/lock0818/blog/612549

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值