MySQL中GUID与binary(16)互转函数
DELIMITER $$ -- 定义语句结束分隔符为$$ -- 将以36个字符表示的GUID值转换为16个二进制字节表示 CREATE FUNCTION fnGuid2Binary($Data VARCHAR(36)) RETURNS binary(16) BEGIN RETURN CONCAT(UNHEX(LEFT($Data,8)),UNHEX(MID($Data,10,4)),UNHEX(MID($Data,15,4)),UNHEX(MID($Data,20,4)),UNHEX(RIGHT($Data,12))); END $$ -- 将以16个二进制字节表示的GUID值转换为36个字符表示 CREATE FUNCTION fnBinary2Guid($Data BINARY(16)) RETURNS char(36) BEGIN RETURN CONCAT(HEX(LEFT($Data,4)),'-', HEX(MID($Data,5,2)),'-', HEX(MID($Data,7,2)),'-',HEX(MID($Data,9,2)),'-',HEX(RIGHT($Data,6))); END $$
COMB数据类型的基本设计思路是这样的:既然UniqueIdentifier数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么我们能不能 通过组合的方式,保留UniqueIdentifier的前10个字节,用后6个字节表示GUID生成的时间(DateTime),这样我们将时间信息与 UniqueIdentifier组合起来,在保留UniqueIdentifier的唯一性的同时增加了有序性,以此来提高索引效率。也许有人会担心 UniqueIdentifier减少到10字节会造成数据出现重复,其实不用担心,后6字节的时间精度可以达到1/300秒,两个COMB类型数据完全 相同的可能性是在这1/300秒内生成的两个GUID前10个字节完全相同,这几乎是不可能的! |
但是MySQL中并没有原生支持GUID类型,所以只能使用binary(16)来存放GUID值,但是GUID值的高位是放在尾部的,如此一来转换为binary(16)后就无法利用高位来排序了。
所以写了下面两个函数,来实现COMB类型与binary(16)互转
DELIMITER $$ -- 定义语句结束分隔符为$$ -- 将以36个字符表示的GUID值(其中高6位为时间信息,用于排序)转换为16个二进制字节表示 CREATE FUNCTION fnCOMB2Binary($Data VARCHAR(36)) RETURNS binary(16) BEGIN -- 特别注意:表示GUID的文本中最后12个字符为高6位的十六进制文本,这里特别将其提到最前是为了便于利用该值排序 RETURN CONCAT(UNHEX(RIGHT($Data,12))/*将高6位提到最前*/,UNHEX(LEFT($Data,8)),UNHEX(MID($Data,10,4)),UNHEX(MID($Data,15,4)),UNHEX(MID($Data,20,4))); END $$ -- 将以16个二进制字节表示的GUID值(其中高6位为时间信息,用于排序)转换为36个字符表示 CREATE FUNCTION fnBinary2COMB($Data BINARY(16)) RETURNS char(36) BEGIN -- 特别注意:表示COMB值的二进制数组中前6位对应GUID文本中最后12个十六进制文本,在还原时注意拼接的先后顺序 RETURN CONCAT(HEX(MID($Data,7,4)),'-', HEX(MID($Data,11,2)),'-', HEX(MID($Data,13,2)),'-',HEX(MID($Data,15,2)),'-',HEX(LEFT($Data,6))); END $$