应该对KCD发布的GuidToBinary例程进行调整,以解决GUID字符串中时间戳的位布局问题。如果该字符串表示版本1 UUID,如uuid()mysql例程返回的UUID,则时间分量将嵌入到字母1-G中,但不包括D。
12345678-9ABC-DEFG-HIJK-LMNOPQRSTUVW
12345678 = least significant 4 bytes of the timestamp in big endian order
9ABC = middle 2 timestamp bytes in big endian
D = 1 to signify a version 1 UUID
EFG = most significant 12 bits of the timestamp in big endian
当您转换成二进制文件时,最佳的索引编制顺序是:EFG9ABC12345678D +其余。
您不希望将12345678交换为78563412,因为大端已产生最佳的二进制索引字节顺序。但是,您确实希望将最高有效字节移到较低字节的前面。因此,EFG首先进入,然后是中间位和低位。一分钟内用uuid()生成一打左右的UUID,您应该看到此顺序如何产生正确的排名。
select uuid(), 0
union
select uuid(), sleep(.001)
union
select uuid(), sleep(.010)
union
select uuid(), sleep(.100)
union
select uuid(), sleep(1)
union
select uuid(), sleep(10)
union
select uuid(), 0;
/* output */
6eec5eb6-9755-11e4-b981-feb7b39d48d6
6eec5f10-9755-11e4-b981-feb7b39d48d6
6eec8ddc-9755-11e4-b981-feb7b39d48d6
6eee30d0-9755-11e4-b981-feb7b39d48d6
6efda038-9755-11e4-b981-feb7b39d48d6
6f9641bf-9755-11e4-b981-feb7b39d48d6
758c3e3e-9755-11e4-b981-feb7b39d48d6
前两个UUID的生成时间最接近。它们仅在第一个块的最后3个半字节中变化。这些是时间戳的最低有效位,这意味着当我们将其转换为可索引的字节数组时,我们希望将其向右推。作为反例,最后一个ID是最新的,但是KCD的交换算法会将其放在第三个ID之前(dc之前的3e,第一个块的最后一个字节)。
正确的索引顺序为:
1e497556eec5eb6...
1e497556eec5f10...
1e497556eec8ddc...
1e497556eee30d0...
1e497556efda038...
1e497556f9641bf...
1e49755758c3e3e...
请参阅本文以获取支持信息:http : //mysql.rjweb.org/doc.php/uuid
***请注意,我不会从时间戳的高12位中拆分版本半字节。这是您示例中的D小节。我只是把它放在前面。因此,我的二进制序列最终是DEFG9ABC等。这意味着我所有索引的UUID都以相同的半字节开头。这篇文章做同样的事情。