文档章节

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

6pker
 6pker
发布于 2016/02/01 14:29
字数 490
阅读 821
收藏 6

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

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

  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个


© 著作权归作者所有

共有 人打赏支持
6pker
粉丝 51
博文 98
码字总数 59361
作品 0
浦东
程序员
hilo高低位算法的优点和用途(非Hibernate主键策略)

开门见山地说,hilo高低位算法的用途,或者说目前为止我所见过的用途,就是——编号生成! 通常订单编号、产品编号、物流编号、工人编号、批次编号等等各种各样的编号,都是由数字构成,有得...

Awisper
2015/12/17
1K
0
Hibernate的generator属性之意义【转】

Hibernate的generator属性之意义 本文讲述Hibernate的generator属性的意义。Generator属性有7种class,本文简略描述了这7种class的意义和用法。 Hibernate的Generator属性有7种class,本文简...

houyiwujing
2012/02/28
0
0
Hibernate的generator属性的意义

本文讲述Hibernate的generator属性的意义。Generator属性有7种class,本文简略描述了这7种class的意义和用法。 Hibernate的Generator属性有7种class,本文简略描述了这7种class的意义和用法。...

黄梦巍
2013/06/26
0
0
常用Hibernate 主键生成策略

ORM映射基本原理 1. 基于相同实体类和表,实现相互映射,类的对象对应了表中的记录,不同对象对应不同的记录,不同的记录对应不同的对象 2. 表中不同的记录通过主键来区分,不同的对象通过对...

徐文瑞
2013/03/09
0
1
4.01-Hibernate中主键生成的策略

1)identity:主键自增,由数据库来生成主键, 在我们创建实体时,不需要手动添加主键,而是由数据库自动生成主键 2)increment:主键自增,有hibernate来维护(生成),先通过查询数据库中主...

静以修身2025
2017/11/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

【大福利】极客时间专栏返现二维码大汇总

我已经购买了如下专栏,大家通过我的二维码你可以获得一定额度的返现! 然后,再给大家来个福利,只要你通过我的二维码购买,并且关注了【飞鱼说编程】公众号,可以加我微信或者私聊我,我再...

飞鱼说编程
今天
1
0
Spring5对比Spring3.2源码之容器的基本实现

最近看了《Spring源码深度解析》,该书是基于Spring3.2版本的,其中关于第二章容器的基本实现部分,目前spring5的实现方式已有较大改变。 Spring3.2的实现: public void testSimpleLoad(){...

Ilike_Java
今天
1
0
【王阳明心学语录】-001

1.“破山中贼易,破心中贼难。” 2.“夫万事万物之理不外于吾心。” 3.“心即理也。”“心外无理,心外无物,心外无事。” 4.“人心之得其正者即道心;道心之失其正者即人心。” 5.“无...

卯金刀GG
今天
2
0
OSChina 周三乱弹 —— 我们无法成为野兽

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @ _刚刚好: 霸王洗发水这波很骚 手机党少年们想听歌,请使劲儿戳(这里) hahahahahahh @嘻酱:居然忘了喝水。 让你喝可乐的话, 你准忘不了...

小小编辑
今天
10
0
vm GC 日志 配置及查看

-XX:+PrintGCDetails 打印 gc 日志 -XX:+PrintTenuringDistribution 监控晋升分布 -XX:+PrintGCTimeStamps 包含时间戳 -XX:+printGCDateStamps 包含时间 -Xloggc:<filename> 可以将数据保存为......

Canaan_
昨天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部