PHP / MySQL:存储和检索UUIDS

时间:2010-05-15 05:31:28

标签: php mysql uuid

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

 UNHEX(REPLACE(UUID(),'-',''))

请原谅我的无知,但有没有一种简单的方法可以使用PHP,然后在需要时将其转回字符串以便于阅读?

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

编辑:

找到答案的一部分:

 $bin = pack("h*", str_replace('-', '', $guid));

你怎么打开它?

3 个答案:

答案 0 :(得分:11)

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

包:

$binary =  pack("h*", str_replace('-', '', $string));

打开包装

$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);

有没有人能看到这个问题?

答案 1 :(得分:2)

如@Johan所述,您需要使用uppercase H (Hex string, high nibble first)才能与MySQL HEX / UNHEX函数兼容

function uuid_to_bin($uuid){
  return pack("H*", str_replace('-', '', $uuid));
}

仅使用unpack()join()方法,可以更紧凑地解码回UUID函数。 注意:您需要name the unpack array parameters / keys in order not to be overwritten

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

对于旧版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 ;

答案 2 :(得分:1)

对于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);

或使用功能进行更多组织:

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);
}

对于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);
}