我正在尝试编写一个MySQL存储函数来生成v4 UUID,如RFC 4122的4.4节(http://www.ietf.org/rfc/rfc4122.txt)中所述。经过一些调整后,我最初的天真努力如下:
CREATE FUNCTION UUID_V4()
RETURNS BINARY(16)
READS SQL DATA
BEGIN
SET @uuid = CONCAT(
LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' ),
LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' ),
LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' ),
LPAD( HEX( FLOOR( RAND() * 4294967296 ) ), 8, '0' )
);
SET @uuid = CONCAT(
SUBSTR( @uuid FROM 1 FOR 12 ),
'4',
SUBSTR( @uuid FROM 14 FOR 3 ),
SUBSTR( 'ab89' FROM FLOOR( 1 + RAND() * 4 ) FOR 1 ),
SUBSTR( @uuid FROM 18 )
);
RETURN UNHEX(@uuid);
END
根据MySQL的UUID()
功能,上述功能非常慢:几乎比内置BENCHMARK()
慢100倍。如果没有使用MySQL的C API编写UDF,我可以在这里进行任何改进,比如说,从运行时中减去一个数量级的数量级吗?
如果已经存在,备受推崇的UUID UDF或存储过程,我也很高兴听到这个消息。
答案 0 :(得分:9)
我没有测试这是正确性还是性能。这只是一个而不是两个连接的想法。
create function uuid_v4()
returns binary(16)
begin
set @h1 = lpad(hex(floor(rand() * 4294967296)), 8, '0');
set @h2 = lpad(hex(floor(rand() * 4294967296)), 8, '0');
set @h3 = lpad(hex(floor(rand() * 4294967296)), 8, '0');
set @h4 = lpad(hex(floor(rand() * 4294967296)), 8, '0');
set @uuid = concat(
@h1,
substr(@h2 from 1 for 4),
'4',
substr(@h2 from 6),
substr('ab89' from floor(1 + rand() * 4) for 1 ),
substr(@h3 from 2),
@h4
);
return unhex(@uuid);
end
;
另外,为什么在你的函数中使用READS SQL DATA
?