唯一标识

 

全局唯一标识符

全局唯一标识符,简称GUID,是一种由算法生成的唯一标识,通常表示成3216进制数字(09AF)组成的字符串,如:{21EC2020-3AEA-1069-A2DD-08002B30309D},它实质上是一个128位长的二进制整数。GUID一词有时也专指微软对UUID标准的实现。

GUID的主要目的是产生完全唯一的数字。在理想情况下,任何计算机和计算机集群都不会生成两个相同的GUIDGUID的总数也足够大,达到了2^128个,所以随机生成两个相同GUID的可能性是非常小的,但并不为0

由于GUID生成的算法和内部组成结构有多种,且网络上很难找到它详细的生成算法,所以这里将不做介绍。

MongoDBObjectId

1)     Time

时间戳。将objectid的前4位进行提取,然后按照十六进制转为十进制这个数字就是一个时间戳。通过时间戳的转换,可以很容易看清时间格式。

2)    Machine

机器。接下来的三个字节是所在主机的唯一标识符,一般是机器主机名的散列值,这样就确保了不同主机生成不同的机器hash值,确保在分布式中不造成冲突,这也就是在同一台机器生成的objectId中间的字符串都是一模一样的原因。

3)    PID

进程ID。上面的Machine是为了确保在不同机器产生的objectId不冲突,而pid就是为了在同一台机器不同的mongodb进程产生了objectId不冲突,接下来的两位就是产生objectId的进程标识符。

4)    INC

自增计数器。前面的九个字节是保证了一秒内不同机器不同进程生成objectId不冲突,后面的三个字节是一个自动增加的计数器,用来确保在同一秒内产生的objectId也不会发现冲突,允许2^24等于16777216条记录的唯一性。

总的来看,objectId的前4个字节时间戳,记录了数据创建的时间;接下来3个字节代表了所在主机的唯一标识符,确定了不同主机间产生不同的objectId;后2个字节的进程id,决定了在同一台机器下,不同mongodb进程产生不同的objectId;最后通过3个字节的自增计数器,确保同一秒内产生objectId的唯一性。ObjectId的这个主键生成策略,很好地解决了在分布式环境下高并发情况主键唯一性问题

学习借鉴

objectId生成规则,我们可以根据实际需求来创建自己的唯一标识,比如:如果不需要考虑并发情况下,我们可以按时间四字节,自增ID五字节这样来组织生成唯一标识。

数据的展示

我们知道,二进制转8进制,可以使用421法,转16进制可以使用8421法,八进制由0-7数字组成,16进制由0-9 A-F组成,如:(10111010)2=(272)8=(BA)16。同理,我们可以推出有7进制(周一到周天)26进制(a-z)52进制(a-z A-Z),64进制(a-z,A-Z,0-9,/,+)等及其计算方法。

由转换规则,可以知道,283位对1位,2164位对1232,就是5位对1位,264就是6位对1位,掌握这个规则对我为接下来减少数据表现位数很有用。我们知道,GUID128位二进制表示的(16字节)可以转换成3216进制表示的字符串或2264进制表示的字符串,就是这样得出来的。

GUID无损压缩

网络上流行一种做法:

byte[] buffer = Guid.NewGuid().ToByteArray();  

long long_guid=BitConverter.ToInt64(buffer, 0)

这样就会得到一个类似于  5472976187161141196 19位长度的数字序列。对这串十进制数还可以在转换,转换成64进制数表示,可以缩到12

两个疑问:

l  是无损压缩,那么可以还原吗

l  由上一章节的推理,怎么可以缩到用19位数字表示呢?

MSDN查找BitConverter.ToInt64方法,我们发现这样一段话:

ToInt64 方法将字节转换为索引中startIndexstartIndex + 7,以Int64的值。字节数组中的顺序必须反映字节排序方式的计算机系统的体系结构 ; 有关详细信息,请参阅注解部分中的BitConverter类主题。

 

真现大白了,原来ToInt64方法,只取bufferstartIndex开始向后加7个字节的值。也就是说,我们16字节的高8个字节被忽略掉了。GUID理想情况下,要2^128个数据才会出现冲突,而转换后,把字节数半,也就是2^64数据就会出现冲突。

使用低8字节的GUID,我的机器运行1个多小时,计算2千万以上数据,没有出现过冲突。

 

总结

1.     如果低八字节的GUID满足需求,那我们可以使用低八字节来表示唯一标识位数我们可以转换成64进制表示,也就是12位就可以了。

2.     某些系统,需要并发产生唯一标识,我们可以根据objectid生成规则,在根据实际需求生成唯一标识。

原文地址:https://www.cnblogs.com/tqlin/p/2870321.html