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 ;