写点什么

为什么总是需要无意义的 ID ?(二)

  • 2019-12-27
  • 本文字数:2139 字

    阅读完需:约 7 分钟

为什么总是需要无意义的 ID ?(二)

唯一性

消息队列往往需要对外保证服务质量,可能需要提供包括最多一次、最少一次和正好一次在内的服务质量,由于网络可能存在超时等不确定性,当我们想要实现正好一次时,就一定需要一种机制能够在接收方识别发送方发出的重复消息,在这时就需要使用唯一的标识符来解决这个问题:



我们在之前的系列文章 为什么 TCP 建立连接需要三次握手 提到的 TCP 连接中的序列号也是一个唯一的标识符,它能够帮助我们判断对数据进行去重,保证应用层的协议不会收到异常的数据包,这些场景都需要用到标识符的唯一性,唯一性为我们带来的就是精确识别对象的能力。


在与网络相关的场景下,使用唯一 ID 的例子非常普遍,假如我们想通过支付宝或者微信的 API 向其他人发起一笔转账,如果这次请求发生了超时,那么我的这笔转账请求到底有没有被处理呢?



当前的节点对于这笔转账请求的结果是不知道的,如果这时重新请求可能会发生二次转账这类严重的问题,但是如果不重新请求,转账可能没有生效,这时如果我们引入一个无意义的 ID 来帮助接收方识别请求的唯一性就能很好地解决这个问题:


  1. 如果接收方已经成功处理 ID 对应的请求,那么就直接返回;

  2. 如果接收方没有处理 ID 对应的请求,就正常进行处理;


为了保证请求的唯一性,根据业务对于唯一性要求的强弱,我们需要在接收方对 ID 进行存储,可以在内存中,也可以在数据库中,最重要的是唯一的 ID 为接收方提供了判断重复的重要依据。


除了在不稳定的网络中,数据库也包含 ID 标识符这一概念,我们在数据库中往往叫做主键,它在一般情况下都是一个递增的唯一整数,绝大多数的表都会使用 ID 作为表的主键来保证数据的唯一性,当我们想要对数据进行增删改查等操作时,使用主键 ID 查询数据也是性能最优并且最不容易出现问题的做法。

无意义

无意义的意思其实就是 ID 中不应该包含任何与具体场景或者业务相关的内容,包含这些内容并不是不可以,只是一旦出现这些内容,要么 ID 重复的可能性会增加,这很可能对我们的业务逻辑造成比较严重的影响,以我们的身份证号为例,它的 18 位数字(或符号)大多都是有意义的。



这 18 位数字中的前 6 位表示的是地区,也就是省份、城市和区县,随后的 8 位表示的是出生年月日,接下来的 3 位才同时表示 ID 和性别,最后 1 位用于做校验码防止出现身份证号输错的情况。用上述图中的黄色部分中有一半的数字是用来表示出生的男性,另一半表示出生的女性,所以如果同一个地区的同一天,同时出生了 501 位男性或者女性就会导致潜在的重复问题。


上面谈到的问题其实也是我们在各种业务场景中经常能够遇到的问题,18 位的数字中真正用于表示序列的 ID 其实只有 1000 的一半,如果 18 位数都是无意义的,那它们可以表示 10 亿亿个人,但是一旦在 ID 中引入了业务上的具体信息,就增加了冲突的可能性。


业务记录上主键的长度往往都是固定的,大多数业务的主键都会使用整数,它的上限一般就是 2^64,如果这些位数都用来表示记录的 ID,那么在有生之年基本上是不可能被使用完的,但是一旦我们将业务信息加入 ID,就会让原本无意义的 ID 变得有意义从而影响它的唯一性。


另一个比较类似的例子其实是分布式的 ID 生成器,Snowflake 算法会为 64 个比特的整数赋予不同的信息:


范围长度作用
0-01不使用
1-4141毫秒级时间戳
42-465数据中心标识符
47-515机器标识符
52-6312序列号


从这个设计来看,我们的假设其实是一台机器上一毫秒最多只能生成 4096 个 ID,一旦超过了这个这个数量就有可能导致 ID 冲突或者乱序,从而失去其唯一性;这个算法中涉及的时间戳、数据中心标识符、机器标识符都没有办法解决唯一性的问题,哪怕这三者完全相等,最终还是有冲突的可能,我们仍然需要使用无其他意义的序列号来保证 ID 的唯一。

总结

其实不难看出,使用无意义 ID 的主要目的就是利用它的唯一性保证对象的标识符不会发生冲突,无意义 ID 的唯一作用就是保证唯一性,这能帮助我们避免业务字段可能存在潜在冲突的可能,这也提示我们想要使用联合字段构成主键时一定要深思熟虑。


如果我们想要在具有唯一性的标识符中加入业务信息,一定要注意这可能会减少用于保证唯一性的『空间』,当然对于一个足够大的空间来说,这其实并没有什么问题;但是类型为 int64 的 ID 中加入业务数据还是需要仔细思考可扩展性以及预留的信息是否足够业务的发展。


到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:


  • 软件工程还有哪些场景利用了 ID 的唯一性?

  • 在日常生活中除了身份证号之外,还有哪些 ID 也有比较高的冲突可能性?


如果对文章中的内容有疑问或者想要了解更多软件工程上一些设计决策背后的原因,可以在博客下面留言,作者会及时回复本文相关的疑问并选择其中合适的主题作为后续的内容。

相关文章


本文转载自 Draveness 技术博客。


原文链接:https://draveness.me/whys-the-design-meaningless-identifier


2019-12-27 11:33832

评论

发布
暂无评论
发现更多内容

接龙工具(源码+文档+部署+讲解)

深圳亥时科技

高并发编程/并行任务组件ForkJoinPool工作窃取算法设计思路分析

肖哥弹架构

Java 并发编程 高并发

FaceTime成诈骗“帮凶”,苹果是怎么一步步丢掉“安全”光环的?

脑极体

AI

搭建一个pandabuy淘宝代购集运系统大概需要多少成本?

tbapi

Pandabuy 反向海淘系统

鸿蒙开发案例:分贝仪

zhongcx

鸿蒙

《使用Gin框架构建分布式应用》阅读笔记:p393-p437

codists

golang gin 编程人 codists

2024年文档管理系统排名:十大工具深度对比

爱吃小舅的鱼

文档管理 文档管理软件 文档管理工具

XMind for mac (XMind思维导图)中文版

Mac相关知识分享

荒谬的中台逻辑

agnostic

中台战略

企业必须知道的8款研发需求管理工具,提升效率的秘密

爱吃小舅的鱼

需求管理 需求管理工具 需求管理软件

振兴帮扶监测系统(源码+文档+部署+讲解)

深圳亥时科技

高并发编程/并行任务组件ForkJoinPool设计图分解(高手篇)

肖哥弹架构

Java 并发编程 高并发

Docker Ubuntu php nginx mysql redis开发环境部署教程

百度搜索:蓝易云

强大的音乐制作软件Ableton Live 12 Suite for mac

Mac相关知识分享

鸿蒙开发案例:直尺

zhongcx

Ubuntu20.04开机卡在[OK] Started ****,无法正常开机

百度搜索:蓝易云

社区人员管理系统(源码+文档+部署+讲解)

深圳亥时科技

Microsoft Office 2019 for Mac正式版

Mac相关知识分享

crossover运行命令是什么,怎么用crossover运行exe程序

阿拉灯神丁

windows 命令行 CrossOver Mac下载 Mac电脑软件

项目管理人员的职业规划与发展策略

爱吃小舅的鱼

项目管理 管理项目 敏捷工具

定时导出数据库数据并备份到gitee和邮箱

JYeontu

MySQL 数据库 前端 Node 数据备份

鸿蒙适配一多搭建首页框架

龙儿筝

鸿蒙

揭秘雅通自动化柴油发电机组中的''黑科技''

雅通机电

柴油发电机组 雅通机电

解决Git上传文件到GitHub时收到 “GH001: Large files detected” 错误信息!

百度搜索:蓝易云

项目管理人员的职业规划:从新手到专家

爱吃小舅的鱼

项目管理 企业管理工具 管理项目

如何应对技术栈迁移中的常见问题?

爱吃小舅的鱼

技术栈 团队沟通 技术兼容 团队技能

Ubuntu下Nginx配置ModSecurity详细思路及过程

百度搜索:蓝易云

Photoshop CC 2019 for Mac中文直装版

Mac相关知识分享

视频下载软件Downie 4 for Mac

Mac相关知识分享

电子文档管理软件选购指南:9款产品深度对比

爱吃小舅的鱼

文档管理 文档管理工具 电子文档

grpc多语言通信之GO和DART

百度搜索:蓝易云

为什么总是需要无意义的 ID ?(二)_文化 & 方法_Draveness_InfoQ精选文章