# id-generator-service **Repository Path**: ck-jesse/id-generator-service ## Basic Information - **Project Name**: id-generator-service - **Description**: 基于不同维度的业务规则生成全局唯一、全局有序的分布式ID。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2020-06-13 - **Last Updated**: 2025-04-04 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # id-generator-service `id-generator-service` 产号服务。 1、分布式ID - 基于改造版本的雪花算法生成 > 1)ID长度有64位,等于一个long类型字段的长度; > > 2)ID分配规则如下: > > ![1579228016776](img/1579228016776.png) > > **sign**: 符号位,也就是最高位为0; > > **delta seconds**: 增量秒,长度30位,表示自2019-12-01 00:00:00.000以来的增量秒,可支撑约17年,截至 2036-12-04 18:48:31; > > **worker id**: 机器id,长度21位,机器id基于数据库分配,最大机器id约为209W; > > **sequence**: 序列号,长度13位,表示同一秒内的序列号,最大值为8191/s; 2、渠道id > 1、渠道id = 8位分布式ID > > 2、8位分布式ID范围 10000000-19999999 > > 3、长度8位,支持千万级别 3、商户号 > 1、商户号 = 8位分布式ID + 3位后缀 > > 2、8位分布式ID范围 20000000-29999999 > > 3、长度11位,支持100亿级别 > > 举例:后缀为渠道id的后三位,该后缀可以做为分库分表的业务规则(如:100库10表 / 10库100表),方便路由渠道和商户维度对应的库表做查询 4、用户ID > 1、用户ID = 9位分布式ID + 3位后缀。 > > 2、9位分布式ID的范围:9000000000-9999999999 > > 3、长度12位,支持1000亿级别 > > 举例:后缀为商户id的后三位,该后缀可以做为分库分表的业务规则(如:100库10表 / 10库100表),方便路由用户和商户维度对应的库表做查询。 5、订单号 > 1、基于雪花算法生成; > > 2、可指定前缀和后缀; > > 举例:后缀为用户id的后三位,该后缀可以做为分库分表的业务规则(如:100库10表 / 10库100表),方便路由订单和用户维度对应的库表做查询。 实践: 在电商平台中,随着业务发展,订单的数据量不断增加,到达一定体量后,要继续演进必然会要做分库分表。那么基于哪个维度来做分库分表呢?分库分表具体怎么做呢? 一般订单有两类典型的业务需求: 1、用户侧:基于用户ID查询订单列表。 2、商家侧:基于商户ID查询订单列表。 所以我们可以分别基于用户ID和商家ID作为分片键来做分库分表,这种方式相当于商家侧冗余了一份订单数据,这样商家侧查询订单列表时无需做聚合汇总操作,查询效率更高,也就是说用空间来换时间。 那么是否可以不冗余商家侧的这一份订单数据,同时又达到查询订单列表的高效呢? 下面提供一种实战方案: 1、基于商家ID生成一个业务因子A 2、生成用户ID时,将该业务因子A作为用户ID的一部分 3、生成订单ID时,将该业务因子A作为订单ID的一部分 4、将业务因子A作为分片键来进行分库分表 经过上面4个步骤,达到同一个商家下用户的订单落到相同的库和表上,这样一份订单数据,就可以支持到商家/用户/订单三个维度的查询场景。不过这个方案存在一个缺陷:数据分布不均匀,商家体量大的数据对应就多。 注:该方案中商家ID、用户ID、订单ID可以结合本产号服务来生成。