卡卷网
当前位置:卡卷网 / 每日看点 / 正文

存QQ号码,究竟该用int类型还是string类型?

作者:卡卷网发布时间:2024-12-02 18:55浏览数量:82次评论数量:0次

前腾讯 PCG 员工,非 QQ 业务。

从腾讯内部的实践上,是先用了 int32,后来花了好大的力气,迁移到了 int64(也有说是 uint32,只是我印象看到的是 int64)。

然而我个人觉得这不是一个优秀的实践。需要先明确的是,对于 QQ 这样巨量的产品,从 int32 升级到 int64,可能会比升级到 string 或者其他类型要简单很多,甚至后者可能是做不到的。因而本篇回答更面向,如果设计一个新的类似 QQ 的系统,那么账户系统设计应该考虑哪些问题。

直接使用自增 int / int32 作为 QQ 号码,可能有这些问题:

  • 由于 int32 的范围限制,无法支持巨量账户数量,显而易见
  • 如果账户稀疏(e.g. 存在大量僵尸账号、保留账号、或者为了安全设计了跳跃机制用户 ID 不连续),则支持的账户数量,更比 int32 的范围量级式地减少,以至于一开始认为 int32 范围真的够了,但后来发现并不是
  • 当 int32_t 正数不够用的时候,大聪明一定会想起使用负数范围,重新解释为 uint32_t,但这在日常开发中绝对会带来大量额外开发成本和 bug 概率
  • 很多语言跨平台性不好,加上开发者意识不足,可能导致代码使用 int ,而不是 int32_t 等明确的类型,int 在不同系统上的长度可能并不一致,导致日常 bug 增多,导致堆起难以扩展但又要互相兼容的历史系统
  • 哪怕都使用 int64,那 int64 的范围就一定够吗?
  • 现在说是整数,那就一定永远是整数吗?例如,会不会有类似身份证号,冷不丁多一个 X 的情况出现?
  • int64 在 json 等序列化场景中、部分语言环境中,会有精度问题,需特别留意

另一个需要一并强调的是,QQ 号码也并不适合作为账户 ID 来使用,问题包括:

  • 如果 ID 是自增的,则有安全性问题,包括容易被顺着 ID 爬取数据,容易被猜测账号的注册时间等「场外信息」,容易通过新注册账号的 QQ 号推测你的用户数量
  • ID 与业务逻辑绑死,功能扩展性差,例如,新手前期很容易想到用 QQ 号做关系型数据库的 PK,做 KV 数据库的 Key,但遇到新的功能需求,比如 VIP 靓号,单账户多 QQ 号,换 QQ 号等,会极大加重这些功能设计的心智负担,并可能导致无数个功能模块需要同步设计方案进行升级,同时带来大量系统运行开销
  • ID 与业务逻辑绑死,系统扩展性与维护性差,例如用户有冷有热,导致不同区间的 QQ 号访问压力不一致,例如 QQ 号很可能由于安全等因素,后期需要设计独立的、复杂的生成规则,这可能导致 QQ 号生成不连续,不均衡,不利于一些负载均衡、存储等组件的性能效果

在这一点上,后来的微信做的稍好,使用了一个用户不可见的整数,作为账户 ID,而手机号、关联QQ号、可以被搜索到的字符串账户 ID,本质都是「唯一昵称」而已。只是我印象里似乎也听闻,微信也经历过账户 ID 由 int32 迁移为 int64 的历史,不确定。


回到正题,如果让我主导设计,我会认为:

  • QQ 号码是「给用户看的」纯业务字段,且不会大面积用于数字计算,因而可以当作「唯一昵称」对待,在数据库和网络服务接口中都设计为 string 是可以的,从而迎接未来各种千奇百怪的需求
  • 除了在负责账户信息的地方负责输入校验,其他系统(至少是长期系统)均不能假定 QQ 号码一定是纯数字,需要验证的输入的地方交给负责账户信息的服务来统一处理
  • 使用 UUID、雪花 ID、类 MongoDB UID 等方案,作为账户的实体唯一 ID
  • 业务中,使用账户 ID 定位账户实体,而不是「昵称」


楼顶有人说 int64 作为内部规范保留,我在 PCG 期间尚未听说,可能是仅限 QQ 内部的规范,设立规范算是个好的出发点,但并不完善,猜测实施起来也会有边界模糊的情况,问题可能包括:

  • 应该先强调,实体 ID 与业务字段彻底隔离,「昵称」更建议 string,实体 ID 使用 UUID 或类似方案,其他使用整数的地方使用 int64,而不是让人一眼看上去像是「建议使用 int64 作为用户 ID」
  • 在使用整型的地方,应该统一为有符号 int64 还是无符号 uint64?不同业务之间是存在矛盾的,而不统一还是会有各种各样的问题
  • 可能存在一些特定领域的数据,只有 32bit,例如可能有一些 digest 算法的输出就是 32bit 的,此时使用 int64 高位一定是全 0,由于符号位不同还可能导致数据转换时有更多 bug 可能,这时候是否还要接着使用 int64?
  • 如何处理与外部系统、老系统的交互方式和边界?否则「扩散」不可避

所以我认为,必须使用 int64 的规范很有可能仅适合 QQ 号码这一个领域。


总归,大厂也并不是所有实践都值得学习,在腾讯的日子更是令我是大开眼界的,大家为了以最快的速度达成目标,巧妙突破 infra 系统的限制,有着各种各样的骚操作,例如有一次见到:

系统使用 int 作为账户 ID,其中第 x 位是 0 的表示一类账户,是 1 的表示另一类账户,从而实现不加协议字段,但在业务中可以直接位操作判断账户类型的目的


大厂后端总是特别看重高性能、高并发,但我还是觉得,如果能有一些垂直领域企业应用开发的经历,对程序员的思维习惯建设也是难能可贵的,这能够教会我们如何尊重这个世界的多样性。

END

免责声明:本文由卡卷网编辑并发布,但不代表本站的观点和立场,只提供分享给大家。

卡卷网

卡卷网 主页 联系他吧

请记住:卡卷网 Www.Kajuan.Net

欢迎 发表评论:

请填写验证码