You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot REST API是否应返回主键?替代方案及最佳实践咨询

REST API医生标识方案问题解答

你当前使用Spring Boot构建的REST接口如下:

@GetMapping("/v1/search/symptom/{symptom}")
public List<DoctorDTO> getDoctorsForSymptom(@PathVariable("symptom") String symptomQuery){
    List<DoctorDTO> doctorDTOList = this.symptomService.getDoctorsForSymptom(symptomQuery);
    //we can add code here for caching the result to make response faster
    return doctorDTOList;
}

对应的Doctor实体定义:

public class Doctor {
    private long doctorId;
    private String name;
    private int age;
    private String mobileNum;
    private MedicalSpeciality medicalSpeciality;
    private List<Slot> slots;
    private List<DoctorSymptomAssociation> doctorSymtomAssociations;
}

针对你提出的问题,解答如下:

一、不返回主键时如何识别同一医生

  • 使用业务唯一标识:如果mobileNum(手机号)在系统中是唯一且不可变更的,可以用它作为后续请求的标识。注意手机号属于敏感信息,传输和存储需加密处理。
  • 临时令牌映射:返回DoctorDTO时生成带过期时间的临时令牌(如JWT),令牌内嵌医生主键信息。后续请求携带令牌,后端验证后提取主键操作。这种方式避免主键直接暴露,同时保证安全性,但需维护令牌生命周期。
  • 自定义业务编码:为每个医生生成唯一的业务编码(如DOC-2024-0015),编码与主键在数据库关联,返回编码给前端作为标识。编码可设计为无规律但易识别的格式,既规避主键递增特性暴露,又满足业务识别需求。

二、新增UUID字段替代主键返回是否可行

完全可行。你可以在Doctor实体中新增uuid字段(MySQL中用CHAR(36)类型存储),医生创建时自动生成UUID并持久化,接口返回该UUID代替自增主键。

UUID的弊端:

  • 存储占用大:自增bigint是8字节,UUID字符串是36字节,增加存储成本。
  • 索引性能差:UUID无序,插入时会导致索引页频繁分裂,降低写入性能。
  • 可读性弱:不利于日志排查和人工识别。

三、适配MySQL的更优方案

1. 雪花算法生成ID

雪花算法生成64位长整型全局唯一ID,包含时间戳、机器标识、序列号,具备递增特性。相比UUID:

  • 存储占用与自增主键一致(8字节),节省空间。
  • 递增特性避免索引页分裂,写入性能更优。
  • 可读性优于UUID,且不暴露业务数据。
    实现时可新增snowflakeId字段,创建医生时生成并存储,接口返回该ID。

2. MySQL原生短UUID

利用MySQL的UUID_SHORT()函数生成64位整数型短UUID,作为医生的唯一标识字段。该ID是全局唯一的整数,存储和索引性能与自增主键一致,同时避免了自增主键的暴露风险。

3. 缓存映射临时标识

若不想新增数据库字段,可在返回DTO时生成随机字符串作为临时标识,将标识与医生主键存入Redis并设置过期时间。后续请求携带临时标识,后端从Redis中取出主键进行操作。此方式无需修改数据库,但需维护缓存的过期策略,防止内存溢出。


内容的提问来源于stack exchange,提问作者Mayank Kumar Thakur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 05:45:33