Django微服务中用UUID作主键或新增UUID字段哪种更合理?
问题描述
我正在开发一个包含4个Django服务的微服务项目,使用dj-rest-auth处理登录与注册流程。各服务拥有独立数据库,用户信息存储于账号服务,其余3个服务通过API请求获取用户信息。目前我只能获取登录用户的主键(由dj-rest-auth处理),存储记录(如用户位置)时仅保存用户主键,示例代码如下:
user = request.user # 这里保存的是登录用户,但我只能看到主键 lat = 纬度数值 lng = 经度数值
但当账号服务数据库丢失并恢复备份后,可能出现主键与其他服务存储的主键不一致的问题,引发严重故障。我尝试将主键改为UUID字段,想请教该方案是否可行?或是在账号服务用户模型新增UUID字段,并在其他服务中存储该UUID更合适?
两种方案的对比与建议
方案1:将用户模型主键改为UUID
可行,但需要注意几个关键问题:
- 迁移成本高:如果已有生产数据,需要编写迁移脚本将原整数主键转换为UUID,同时其他服务中已存储的旧主键也需同步更新,整体工作量较大。
- dj-rest-auth适配调整:默认dj-rest-auth依赖整数类型的用户主键,需修改认证逻辑(比如JWT的
user_id字段配置、Token模型的关联字段类型),确保认证流程能正确识别UUID类型的用户ID。 - 全服务同步修改:所有依赖用户主键的服务都要将对应字段类型从
IntegerField改为UUIDField,避免出现数据类型不匹配的错误。
方案2:新增UUID字段作为用户唯一标识(更推荐)
这个方案对现有系统侵入性最小,是更稳妥的选择:
- 改动成本低:无需修改用户模型的主键,仅需在账号服务的User模型中新增一个
uuid字段,配置为models.UUIDField(default=uuid.uuid4, unique=True, editable=False)即可自动生成全局唯一的UUID。 - 兼容现有认证流程:dj-rest-auth的原有逻辑无需大幅调整,只需在登录成功后将用户的UUID返回给其他服务,或在其他服务请求用户信息时携带UUID作为标识。
- 备份恢复无风险:UUID是全局唯一的,即使账号服务数据库恢复备份,UUID不会因主键重置而改变,其他服务存储的UUID可直接对应到恢复后的用户数据,避免主键不匹配的故障。
- 过渡平滑:可以逐步将其他服务中存储的用户主键替换为UUID,期间可同时保留主键和UUID字段做兼容,待所有服务完成切换后再移除旧主键字段。
实施步骤参考
- 先在账号服务的User模型中添加UUID字段,确保其自动生成且唯一。
- 修改账号服务的用户信息接口,将UUID字段返回给其他服务。
- 逐步更新其他服务的存储逻辑,将原用户主键存储改为UUID存储。
- 若存在历史数据,可先在其他服务中新增UUID字段,通过调用账号服务的API批量更新已有记录的UUID值,完成后再移除原主键字段。
内容的提问来源于stack exchange,提问作者Niloofar
相关产品推荐
相关产品推荐

