在各类购物App中,都会遇到商家发放的优惠券
当用户抢购商品时,生成的订单会保存到tb_voucher_order
表中,而订单表如果使用数据库自增ID就会存在一些问题
如果我们的订单id有太明显的规律,那么对于用户或者竞争对手,就很容易猜测出我们的一些敏感信息,例如商城一天之内能卖出多少单,这明显不合适
随着我们商城的规模越来越大,MySQL的单表容量不宜超过500W,数据量过大之后,我们就要进行拆库拆表,拆分表了之后,他们从逻辑上讲,是同一张表,所以他们的id不能重复,于是乎我们就要保证id的唯一性
那么这就引出我们的全局ID生成器
了
为了增加ID的安全性,我们可以不直接使用Redis自增的数值,而是拼接一些其他信息
ID组成部分
那我们就根据我们分析的ID生成策略,来编写代码
public static void main(String[] args) {
//设置一下起始时间,时间戳就是起始时间与当前时间的秒数差
LocalDateTime tmp = LocalDateTime.of(2022, 1, 1, 0, 0, 0);
System.out.println(tmp.toEpochSecond(ZoneOffset.UTC));
//结果为1640995200L
}
完整代码如下
@Component
public class RedisIdWorker {
@Autowired
private StringRedisTemplate stringRedisTemplate;
//设置起始时间,我这里设定的是2022.01.01 00:00:00
public static final Long BEGIN_TIMESTAMP = 1640995200L;
//序列号长度
public static final Long COUNT_BIT = 32L;
public long nextId(String keyPrefix){
//1. 生成时间戳
LocalDateTime now = LocalDateTime.now();
long currentSecond = now.toEpochSecond(ZoneOffset.UTC);
long timeStamp = currentSecond - BEGIN_TIMESTAMP;
//2. 生成序列号
String date = now.format(DateTimeFormatter.ofPattern("yyyy:MM:dd"));
long count = stringRedisTemplate.opsForValue().increment("inc:"+keyPrefix+":"+date);
//3. 拼接并返回,简单位运算
return timeStamp << COUNT_BIT | count;
}
}
Field | Type | Collation | Null | Key | Default | Extra | Comment |
---|---|---|---|---|---|---|---|
id | bigint unsigned | (NULL) | NO | PRI | (NULL) | auto_increment | 主键 |
shop_id | bigint unsigned | (NULL) | YES | (NULL) | 商铺id | ||
title | varchar(255) | utf8mb4_general_ci | NO | (NULL) | 代金券标题 | ||
sub_title | varchar(255) | utf8mb4_general_ci | YES | (NULL) | 副标题 | ||
rules | varchar(1024) | utf8mb4_general_ci | YES | (NULL) | 使用规则 | ||
pay_value | bigint unsigned | (NULL) | NO | (NULL) | 支付金额,单位是分。例如200代表2元 | ||
actual_value | bigint | (NULL) | NO | (NULL) | 抵扣金额,单位是分。例如200代表2元 | ||
type | tinyint unsigned | (NULL) | NO | 0 | 0,普通券;1,秒杀券 | ||
status | tinyint unsigned | (NULL) | NO | 1 | 1,上架; 2,下架; 3,过期 | ||
create_time | timestamp | (NULL) | NO | CURRENT_TIMESTAMP | DEFAULT_GENERATED | 创建时间 | |
update_time | timestamp | (NULL) | NO | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP | 更新时间 |
Field | Type | Collation | Null | Key | Default | Extra | Comment |
---|---|---|---|---|---|---|---|
voucher_id | bigint unsigned | (NULL) | NO | PRI | (NULL) | 关联的优惠券的id | |
stock | int | (NULL) | NO | (NULL) | 库存 | ||
create_time | timestamp | (NULL) | NO | CURRENT_TIMESTAMP | DEFAULT_GENERATED | 创建时间 | |
begin_time | timestamp | (NULL) | NO | CURRENT_TIMESTAMP | DEFAULT_GENERATED | 生效时间 | |
end_time | timestamp | (NULL) | NO | CURRENT_TIMESTAMP | DEFAULT_GENERATED | 失效时间 | |
update_time | timestamp | (NULL) | NO | CURRENT_TIMESTAMP | DEFAULT_GENERATED on update CURRENT_TIMESTAMP | 更新时间 |