大家好,我是大都督周瑜,最近一位同学遇到了这样一道面试题:MySQL自增ID用完了怎么办?
关注我的公众号IT周瑜,回复“面试题”,可以领取更多精品面试题资料。
这道面试题其实也是一道面试造火箭的面试题,如果ID字段是INT类型,那么最大值约为21亿,如果ID字段是BIGINT类型,最大值则可以达到约为9亿亿,因此只有在数据量特别大的情况下才需要考虑自增ID用完之后怎么办,不过为了大家能拿到心仪的offer,我这里提供以下几种方案。
切换到BIGINT
如果当前字段类型是INT类型,通过修改字段类型,将INT类型升级为BIGINT类型,从而可以大幅提高自增ID的上限。
不过要注意,在已有大量数据的表上进行字段类型修改的操作可能会影响性能,建议使用在线修改工具如pt-online-schema-change以减少影响。
分表分库
通过将数据分散到多个表或数据库中,每个新的表或数据库都可以从1开始使用自增ID。
这种方案的优点是可以显著提高数据处理能力和查询效率,缺点是需要重新调整架构,需要修改业务代码,需要考虑数据迁移等问题。
UUID
一个UUID字符串,比如123e4567-e89b-12d3-a456-426655440000
,是由32个十六进制数字组成的,因此一个UUID总共由128(32*4)个bit组成,也是说理论上有2的128次方个值可以使用,比BIGINT还有多,虽然是全球一起用,但是也很难用完。
不过由于UUID会占用更多的空间和本身的无序性,会影响数据库的插入、查询等操作的效率,需要慎重考虑是否使用。
雪花算法
雪花算法是由之前的Twitter,现在的X开发的分布式ID生成算法,利用机器ID和时间戳来生成64位长整型ID,当然,具体机器ID占几位,时间是到秒还是毫秒,是可以自己修改算法来调整的,百度的UidGenerator,滴滴的TinyID,美团的Leaf都采用了雪花算法。
雪花算法的好处是最终生成的ID是会按时间递增的,但是也要考虑时钟回拨的问题,建议使用,不过BIGINT也是64位长整型ID,所以从支持的上限来看两者是一样的,雪花算法的优势在于更适合分布式环境。
回收已删除的ID
如果对于某个表采用的是假删除,也就是所谓的删除其实只是把isDeleted字段改为true,那么可以考虑是否能把这些被删除的记录进行真删除或迁移到其他库,从而释放这些假删除所占用的ID值。
这种方式需要提前把假删除记录占用的ID值查出来并给新记录使用,需要谨慎使用,以避免ID冲突。
总结
- 自增ID耗尽问题通常与系统设计相关,需要根据具体情况选择合适的解决方案。
- 面试官询问此问题是为了评估候选人对数据库设计、性能优化和问题解决能力的了解。
- 在实际应用中,使用BIGINT类型可以大幅降低ID耗尽的风险,如果真的面临ID耗尽的问题,通常意味着数据库架构需要进行优化或重构。
我是大都督周瑜,喜欢结交朋友,欢迎大家加我微信:dadudu6789,一起交流技术,我经常会在朋友圈分享一些比公众号更有深度的干货内容或面试经验。