Saltar al contenido

Inserción y selección de UUID como binario(16)

Posteriormente a mirar en diversos repositorios y páginas al final hallamos la resolución que te mostraremos ahora.

Solución:

Entonces, como respuesta a los comentarios. La forma correcta de almacenar un UUID de 36 caracteres como binario (16) es realizar la inserción de la siguiente manera:

INSERT INTO sometable (UUID) VALUES
       (UNHEX(REPLACE("3f06af63-a93c-11e4-9797-00505690773f", "-","")))

UNHEX porque un UUID ya es un valor hexadecimal. Recortamos (REPLACE) los guiones en la declaración para reducir la longitud a 32 caracteres (nuestros 16 bytes representados como HEX). Puede hacer esto en cualquier momento antes de almacenarlo, obviamente, por lo que no tiene que ser manejado por la base de datos.

Puede recuperar el UUID de esta manera:

SELECT HEX(UUID) FROM sometable;

En caso de que alguien se encuentre con este hilo y no esté seguro de cómo funciona.

Y recuerda: si estás seleccionando una fila usando el UUID, utilizar UNHEX() bajo la condición:

SELECT * FROM sometable WHERE UUID = UNHEX('3f06af63a93c11e4979700505690773f');

o notación literal (como lo menciona Alexis Wilke):

SELECT * FROM sometable WHERE UUID = 0x3f06af63a93c11e4979700505690773f;

Y no HEX()en la columna:

SELECT * FROM sometable WHERE HEX(UUID) = '3f06af63a93c11e4979700505690773f';

La última solución, mientras funciona, requiere que MySQL HEXes todos los UUID antes de que pueda determinar qué filas coinciden. Es muy ineficiente.

Editar: si está utilizando MySQL 8, debería echar un vistazo a las funciones UUID como se menciona en la respuesta de SlyDave. Esta respuesta sigue siendo correcta, pero no optimiza los índices UUID que se pueden hacer de forma nativa usando esas funciones. Si está en < MySQL 8, puede implementar el polyfill de Devon, que proporciona una funcionalidad idéntica a las versiones anteriores de MySQL.

A partir de MySQL 8, puede usar dos nuevas funciones UUID:

  • BIN_TO_UUID

    SELECT BIN_TO_UUID(uuid, true) AS uuid FROM foo;
    -- 3f06af63-a93c-11e4-9797-00505690773f
    
  • UUID_TO_BIN

    INSERT INTO foo (uuid) VALUES (UUID_TO_BIN('3f06af63-a93c-11e4-9797-00505690773f', true));
    

Este método también admite la reorganización del componente de tiempo del uuid para mejorar el rendimiento de la indexación (ordenándolo cronológicamente), simplemente establezca el segundo argumento en true – esto solo funciona para UUID1.

Si está utilizando el true en UUID_TO_BIN marca para el rendimiento de indexación (recomendado), también debe establecerlo en BIN_TO_UUID de lo contrario, no se volverá a convertir correctamente.

Consulte la documentación para obtener más detalles.

  • https://dev.mysql.com/doc/refman/8.0/en/funciones-misceláneas.html#function_uuid-to-bin
  • http://mysqlserverteam.com/mysql-8-0-uuid-support/

Polyfill para BIN_TO_UUID y UUID_TO_BIN para MySQL 5 con el parámetro swap_flag.

DELIMITER $$

CREATE FUNCTION BIN_TO_UUID(b BINARY(16), f BOOLEAN)
RETURNS CHAR(36)
DETERMINISTIC
BEGIN
   DECLARE hexStr CHAR(32);
   SET hexStr = HEX(b);
   RETURN LOWER(CONCAT(
        IF(f,SUBSTR(hexStr, 9, 8),SUBSTR(hexStr, 1, 8)), '-',
        IF(f,SUBSTR(hexStr, 5, 4),SUBSTR(hexStr, 9, 4)), '-',
        IF(f,SUBSTR(hexStr, 1, 4),SUBSTR(hexStr, 13, 4)), '-',
        SUBSTR(hexStr, 17, 4), '-',
        SUBSTR(hexStr, 21)
    ));
END$$


CREATE FUNCTION UUID_TO_BIN(uuid CHAR(36), f BOOLEAN)
RETURNS BINARY(16)
DETERMINISTIC
BEGIN
  RETURN UNHEX(CONCAT(
  IF(f,SUBSTRING(uuid, 15, 4),SUBSTRING(uuid, 1, 8)),
  SUBSTRING(uuid, 10, 4),
  IF(f,SUBSTRING(uuid, 1, 8),SUBSTRING(uuid, 15, 4)),
  SUBSTRING(uuid, 20, 4),
  SUBSTRING(uuid, 25))
  );
END$$

DELIMITER ;

--
-- Tests to demonstrate that it works correctly. These are the values taken from
-- https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid-to-bin
--
-- If you run these SELECTs using the above functions, the 
-- output of the two columns should be exactly identical in all four cases.
SET @uuid = '6ccd780c-baba-1026-9564-5b8c656024db';
SELECT HEX(UUID_TO_BIN(@uuid, 0)), '6CCD780CBABA102695645B8C656024DB';
SELECT HEX(UUID_TO_BIN(@uuid, 1)), '1026BABA6CCD780C95645B8C656024DB';
SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,0),0), '6ccd780c-baba-1026-9564-5b8c656024db';
SELECT BIN_TO_UUID(UUID_TO_BIN(@uuid,1),1), '6ccd780c-baba-1026-9564-5b8c656024db';

Se incluyen los ejemplos SELECT de https://dev.mysql.com/doc/refman/8.0/en/miscellaneous-functions.html#function_uuid-to-bin que demuestran que el código anterior devuelve exactamente los mismos resultados que la función 8.0 . Estas funciones se consideran DETERMINISTAS ya que siempre producen la misma salida para una entrada dada. Consulte https://dev.mysql.com/doc/refman/8.0/en/create-procedure.html

Si para ti ha sido de provecho este artículo, sería de mucha ayuda si lo compartes con otros programadores así contrubuyes a extender nuestra información.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *