前言
通常,我们采用数值ID(long)/GUID作为全局唯一标识符。
但是,在多线程、高并发情况下,由应用程序生成数值ID容易产生重复,而由数据库生成又会造成性能瓶颈。
而使用Guid.NewGuid()
生成的GUID虽然不会重复,但是它是无序的,不适合作为数据库主键,会产生大量索引碎片,影响性能。
有不有什么方法,能生成既是顺序的,又不会重复的全局唯一标识符?
snowflake
大家可能首先想到的是snowflake,Twitter开源的分布式ID生成算法,它会生成一个long型(64bit)的ID。
其中,前41bit是时间戳,接下来的10bit代表机器ID,防止冲突,后12bit代表序列号,以便在同一毫秒内创建多个ID。
但是,机器ID
导致了无法去中心化,必须有一个全局生成机器ID的机制作为额外协调。
这时,你可以尝试一下NewId。
NewId
NewId是一个连续ID生成器,它使用主机MAC地址,结合时间戳和递增的序列号实现ID生成策略。
由于MAC地址全局唯一,因此NewId无需机器ID这样的额外设施,即可生成按时间顺序排序的全局唯一标识符。
使用方式非常简单。
首先,引用Nuget包NewId
。
然后,设置生成标识符时包含processId(进程Id),保证运行在同一台机器上的多个进程生成的标识符不会重复:
NewId.SetProcessIdProvider(new CurrentProcessIdProvider());
最后,生成GUID:
var guid = NewId.NextGuid();
我们尝试了生成多个GUID,发现确实是连续的:
结论
生成顺序GUID又会造成Id容易被猜测,这时,可以结合我们上次的文章(保护我方Id
如果你觉得这篇文章对你有所启发,请关注我的个人公众号”My IO“