PHP/MySQL:存储和检索UUIDS

Gre*_*reg 7 php mysql uuid

我正在尝试将UUID添加到几个表中,但我不确定存储/检索这些表的最佳方法是什么.我知道使用BINARY(16)代替VARCHAR(36)效率更高.在做了一些研究之后,我还发现你可以将UUID字符串转换为二进制:

 UNHEX(REPLACE(UUID(),'-',''))
Run Code Online (Sandbox Code Playgroud)

原谅我的无知,但有一个简单的方法用PHP,然后在需要时将其转回字符串,以提高可读性?

另外,如果我用它作为主键而不是auto_increment会有很大的不同吗?

编辑:

找到部分答案:

 $bin = pack("h*", str_replace('-', '', $guid));
Run Code Online (Sandbox Code Playgroud)

你怎么打开它?

Gre*_*reg 12

好的 - 试着回答我自己的问题.这是我能想到的最好的:

包:

$binary =  pack("h*", str_replace('-', '', $string));
Run Code Online (Sandbox Code Playgroud)

解压

$string = unpack("h*", $binary);
$string = preg_replace("/([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})/", "$1-$2-$3-$4-$5", $string);
Run Code Online (Sandbox Code Playgroud)

这个人有什么问题吗?

  • 如果您想要与MySQL的(UN)HEX功能兼容,这是使用pack的错误方法.你需要使用pack('H*')(大写H) (5认同)

qde*_*dev 10

正如@Johan提到的,您需要使用大写H(十六进制字符串,高半字节在前)以便与MySQL HEX / UNHEX函数兼容

function uuid_to_bin($uuid){
  return pack("H*", str_replace('-', '', $uuid));
}
Run Code Online (Sandbox Code Playgroud)

更紧凑的解码回 UUID 函数,仅使用unpack()join()方法。 注意:您需要命名解包数组参数/键,以免被覆盖

function bin_to_uuid($bin){
  return join("-", unpack("H8time_low/H4time_mid/H4time_hi/H4clock_seq_hi/H12clock_seq_low", $bin));
}
Run Code Online (Sandbox Code Playgroud)

对于较旧的 MySQL 版本,缺少uuid_to_bin()和函数:bin_to_uuid()

DELIMITER $$
CREATE FUNCTION `fn_uuid_to_bin`(`s` CHAR(36)) RETURNS binary(16)
    DETERMINISTIC

RETURN UNHEX(REPLACE(s, '-', ''))$$

DELIMITER ;

DELIMITER $$
CREATE FUNCTION `fn_bin_to_uuid`(`b` BINARY(16)) RETURNS char(36) CHARSET utf8mb4
    DETERMINISTIC
BEGIN
  DECLARE hex CHAR(32);
  SET hex = HEX(b);
  RETURN LOWER(CONCAT(LEFT(hex, 8), '-', MID(hex, 9,4), '-', MID(hex, 13,4), '-', MID(hex, 17,4), '-', RIGHT(hex, 12)));
END$$

DELIMITER ;
Run Code Online (Sandbox Code Playgroud)


ins*_*ign 6

对于 php >= 5.4,我们可以使用hex2binbin2hex

$binary = hex2bin(str_replace('-', '', $value));


$string = bin2hex($value);
$string = preg_replace('/([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})/', '$1-$2-$3-$4-$5', $string);
Run Code Online (Sandbox Code Playgroud)

或者使用函数进行更多组织:

function uuid2bin($uuid) {
   return hex2bin(str_replace('-', '', $uuid));
}

function bin2uuid($value) {
   $string = bin2hex($value);

   return preg_replace('/([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})/', '$1-$2-$3-$4-$5', $string);
}
Run Code Online (Sandbox Code Playgroud)

对于 Laravel(使用 ID 字段):

public function setIdAttribute($value)
{
   $this->attributes[ 'id' ] = hex2bin(str_replace('-', '', $value));
}

public function getIdAttribute($value)
{
   $string = bin2hex($value);

   return preg_replace('/([0-9a-f]{8})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{4})([0-9a-f]{12})/', '$1-$2-$3-$4-$5', $string);
}
Run Code Online (Sandbox Code Playgroud)