PHP / MySQL: хранение и извлечение UUID

Я пытаюсь добавить UUID в пару таблиц, но я не уверен, что лучший способ сохранить/получить их будет. Я понимаю, что гораздо эффективнее использовать BINARY(16) вместо VARCHAR (36). После проведения небольшого исследования я также обнаружил, что вы можете преобразовать строку UUID в двоичный файл с помощью:

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

простите мое невежество, но есть ли простой способ сделать это с PHP, а затем вернуть его в строку, когда это необходимо, для удобства чтения?

кроме того, будет много разница, если я использовал это как первичный ключ вместо auto_increment?

EDIT:

найдена часть ответа:

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

Как бы вы распаковали его?

2 ответов


Хорошо -- попробую ответить на свой вопрос. Это лучшее, что я мог придумать:

Pack:

$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})/", "----", $string);

есть ли какие-либо проблемы с этим, кто-нибудь может видеть?


как упоминал @Johan, вам нужно использовать верхний регистр H (шестнадцатеричная строка, сначала высокий укус) для того, чтобы быть совместимым с MySQL HEX / UNHEX функции

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

более компактное декодирование обратно в функцию UUID, используя только unpack() и join() методы. внимание: вам нужно назовите параметры / ключи массива распаковки, чтобы не перезаписываться !

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 ;