ID的使用说明原创
金蝶云社区-ooodz
ooodz
7人赞赏了该文章 1,312次浏览 未经作者许可,禁止转载编辑于2020年11月16日 17:57:56

1. ID服务概述

苍穹平台提供了分布式ID服务,用来生成集群环境内全局唯一ID。


ID的类型有long和String,它们之间可以相互转换。

ID使用snowflake算法生成(请百度了解),ID(Long类型)组成:0 time worker sequence。


服务嵌入到微服务节点内,每个微服务节点都含一个ID服务,一个ID服务可含多个woker,worker个数可配置,默认为1。

ID值在一个ID服务的一个worker内的ID产生是严格有序的(递增),由于集群由多个微服务节点同时提供服务,不同节点产生的ID值,顺序存在交错(worker的值交错),但总体上是趋势有序,因生成的时候存在时间差。



2. 使用接口:kd.bos.id.ID

#生成long类型ID值
long genLongId()
long[] genLongIds(int)

#生成String类型ID值(39进制)
String genStringId()
String[] genStringIds(int)

#long与39进制字符互转
String toStringId(long)
long toLongId(String)

#long与36进制字符互转
String longTo36Radix(long)
long longFrom36Radix(String)

#获取id生成时间
Date getCreateTime(long)
Date getCreateTime(String)

DB、ORM里的id接口,最终使用了kd.bos.id.ID (建议直接用这个)。



3.ID编码与长度

ID有long、string两种数据类型,string通过进制编码与long类型转换。


默认long to string使用Base39Code,组成的字符集为:+/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ


另外提供了36进制编码(longTo36Radix),用于不能有+/=字符的场合,字符集:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ


字符集不含小写字母的原因:苍穹产品中对数据库的查询,字符不区分大小写。


long类型对应ksql的bigint,整型长度为19。

39进制,字符最大长度为12。

36进制,字符最大长度为13。



4.FAQ

1)为什么要有单独的ID服务?

数据表的自增字段,在插入值后才产生,但我们的领域模型中,通常需要先产生id值,在模型间引用传递。

自增方式会限制以后使用分表。

而ID服务可用于产生表行主键,也适用于其他需要全局唯一值的场景。

ID的趋势递增特性,做集聚索引,可减少表数据的移动。


2)表主键用ID什么类型好?

作为数据表主键,用long类型,它占8个字节,而字符类型占12~13个字节,数值类型比较更高效。

其他情况根据具体需要选择long/39string/36sting类型。


3)ORM save的时候为什么会产生主键冲突?

从ID生成的原理分析(ID服务内置时间回拨检测机制),在一个集群内,是不可能产生重复ID的。

一般是这种情况引起:ORM query出来的对象再save,此时所有操作都是insert,与已有的行就冲突了。

正确的用法是,ORM load出来的对象才能save,因为load出来的对象有快照,save时对比快照生成对应的增删改SQL。


4)怎么设置对象的主键?

用下面方法,生成唯一ID填补到无主键值的对象(含其分录、子分录对象)。

ORM.create().setPrimaryKey(DynamicObject)




赞 7