电商系统ID生成策略简单介绍

时间:2024-04-13 10:49:06

在系统中生成ID的方式有很多种,现在简单分析一下各种方式的适用场景以及优缺点。

1. UUID. 唯一性,在单体环境下或者分布式环境下都不会出现重复。但是UUID的劣势也是一大堆

 a.没有可读性,导致程序在调试的时候数据不直观,不能像整型ID一样直观的看到大致运行到了哪条记录,如果比对两条数据,也不能很快看出谁先谁后。

 b. 32位字符串太长,占用数据库资源。

 c. 在对主键进行索引的时候,32位字符串进行索引要比整型数据进行索引费事,而且如果使用UUID作为主键并进行了索引,因为需要维护数据库的字符串索引,那么增删改的速度会降低。

 

2. 数据库自增ID. 这是大部分系统中所用的ID生成方式。简单易用,索引效率高。但是一旦涉及到大数据量的分库分表,会出现ID重复的问题。比如说电商网站的订单数据量很大,用两个结构相同的数据库实例A跟B来存储订单数据,A跟B中的表结构也相同。两者订单ID都设置为自增。在没有任何策略的情况下,订单1存入A库,订单2存入B库,这时候两个订单的ID有可能出现重复,因为A跟B在数据库这一层没有直接的关系,各自为战。A根本不知道B的主键自增情况,B也不知道A的情况。

解决办法就是设置指定的步长与初始参数。假如有3个数据库A,B,C来分担数据,那么步长都设置为3,初始值设置为1,2,3. 这样,无论3个数据库各自怎么自增,都不会出现重复现象。

电商系统ID生成策略简单介绍

但是这个带来了扩展性的问题。当数据量加大而想要再增加一个数据库D的时候,就显得非常困难。这时候是不能再简单的设置D一个初始值,因为这样会道来数据重复。解决办法就是数据迁移,然后重新分配初始值与步长。而且这样做需要停止正常业务。

3. 依赖于Redis产生ID. 这是大部分电商网站都使用的方式。Redis是内存操作,速度快,单线程并且能支持高并发,能很好的应对分布式环境。产生方式就是利用键值对的increment操作,key设置为orderId, 每次需要新的ID就在这个键值对上对value加1.

这里有个技巧,就是把最终ID分为两部分,利用当天的时间作为前缀,Redis产生的值作为后缀。如果没有前缀的话,Redis键值对的value产生的ID会越来越大,不好维护。如果用时间作为前缀,比如2020010614(2020-01-06 14:00), 达到指定timeout时间后,比如60分钟,键值对的value就会重新从0开始。因为这时候前缀的值已经变了,所以后缀重复了,但最终的整体ID是不重复的。具体的实现逻辑如下代码。

电商系统ID生成策略简单介绍

 

电商系统ID生成策略简单介绍

此外,可以在生成的id中加入业务标识,组装成更具体的ID. 以天猫的订单号为例,同一个账户的不同订单,最后都有一个2043标识。这个标识类似于用户的哈希值,在分布式环境或者分布式数据库中,对于路由至关重要。举个例子,在处理该用户的订单的时候,后台有N个负载均衡的数据库实例, 这时候通过一定的路由算法,会把结尾是2043的订单都路由到实例B数据库中,因为那里存着该用户的所有详细数据,存取数据性能很高。

电商系统ID生成策略简单介绍

电商系统ID生成策略简单介绍