解决雪花算法前后端不一致的问题

一、问题描述

  前后端在进行数据交互的时候,通过雪花算法生成的 id 主键出现前后端不一致的情况;

二、问题分析

  使用雪花算法生成的 id 主键超出了 前端 js 的 number 类型的最大数值;

  • JAVA 中的 Long 类型的最大值为(2^63-1)也就是 9223372036854775807;
  • JS 的 number 类型所支持的最大值为 (2^53)也就是 9007199254740992;
  • 一旦前端所接收的数字超过了 JS 的 number 类型的最大值,就会出现精度丢失,从而导致前后端的值不一致。

三、解决方案

  解决思路:后端的 ID(Long) 通过转换成 String 类型提供给前端使用,前端使用 js 中的 string 就不会出现精度丢失了。 而前端把 String 类型的数字传回服务端的时候,可以直接使用 Long 类型进行接收( Spring 反序列化参数接收默认支持的行为)。


3.1 方案一:添加 yaml 配置
  通过在 application.yml 中加上以下配置进行将所有数字都变成字符串,包括 long 和 int 类型;

spring:
  jackson:
    generator:
      writeNumbersAsStrings: true

3.2 方案二:引入注解
@JsonFormat 或者 @JsonSerialize

// @JsonFormat 注解示例
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
 
@Data
public class User {
    /**
     * 用户id
     */
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private Long id;
}
// @JsonSerialize 注解示例
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
 
@Data
public class User {
    /**
     * 用户id
     */
    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
}

四、为什么不直接用String 作为主键

  就该问题上来说,使用 String 确实能解决精度丢失的问题,但是使用字符串不建议直接作为主键,理由如下:

  1. 存储空间:相比于数值类型,字符串通常占用更多的存储空间。如果数据集很大或者主键被频繁使用,字符串类型的主键可能会占用大量的存储空间,增加存储成本。

  2. 查询性能:字符串类型的主键在进行索引和查询时通常比数值类型的主键更慢。字符串比较需要逐个字符进行比较,而数值类型可以进行简单的比较操作。当数据集较大时,字符串比较的开销可能会显著影响查询性能。

  3. 排序和范围查询:字符串类型的主键在进行排序和范围查询时可能会遇到一些困难。字符串排序通常是基于字符的字典顺序进行的,而不是基于数值大小。这可能导致排序结果不符合预期。另外,对于范围查询,字符串类型的主键可能需要进行额外的计算和处理才能正确执行范围查询。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jc_caterpillar

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值