开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 16 天,点击查看活动详情”
前言
连续写了这多天的redis有关的东西,今天我来写写有关业务的一些要点。而今天这篇就是有关全局唯一id的。
全局唯一id的重要性
首先来说说为什么我们需要这个全局唯一id。有些人可能会说这“玩意怎么会重要呢,使用数据库的自增不就好了?”。其实这句话对也不对。数据库的自增确实符合全局唯一id的几个要求(全局唯一性,单调递增)。但是有时出于需求我们不得不进行分库分表时,数据库自增就没有办法保持全局一致性了。同时在一些订单业务时,如果我们也使用数据库自增的话,就非常容易被别有用心之人知道我们对应的信息,这时我们就需要别的办法生成全局唯一id了。所以接下来介绍几种生成方法(重点介绍UUID)
UUID
UUID(Universally Unique Identifier)即唯一通用识别码。这是由我们自己定义的唯一id生成器。由我们自己在程序中生成,说明其api调用非常方便,也有别人直接写好了的api引入对应的库即可。像java就有着对应的api。
`UUID uuid = UUID.randomUUID();
但是我们也可以自己写一个,以下为对应代码。
public long nextId(String prefixKey)
{
//先定义一个最初的时间,就是定义的变量
//然后获取当前的时间戳
long seconds = Instant.now().getEpochSecond();
//两者相减
long timeStamp = seconds-BEGIN_BITS;
//先生成key,用时间也是为了方便统计
String format = LocalDateTime.now().format(
DateTimeFormatter.ofPattern("yyyy-MM-dd")
);
String key = prefixKey+":"+format;
//从redis中拿到自增序列号
Long increment = stringRedisTemplate.opsForValue().increment(key);
//这里先向左平移32位,然后异或序列号(因为后面都是0)
return timeStamp<<32|increment;
首先来说说我实现的思路就是用时间戳然后向左移动32位,最后再异或一个自增,除非两个部分都一样(时间戳和自增的结果),不然一定不是重复的。
缺点
为了保证不重复,我们往往需要比较长的数字,这就造成其传输数据量比较大,不适合做主键,同时其代表的意思往往比较抽象。