2012-06-08 4 views
71

Basé sur la réponse à la question, UUID performance in MySQL, la personne qui répond suggère de stocker UUID comme un nombre et non comme une chaîne. Je ne suis pas sûr de comment cela peut être fait. Quelqu'un pourrait me suggérer quelque chose? Comment mon code ruby ​​gère cela?Comment stocker uuid comme numéro?

+5

Les problèmes de performances surviennent uniquement lorsque vous utilisez l'UUID comme clé primaire, car les UUID ne sont pas des clés primaires très efficaces. Pourquoi avez-vous besoin d'UUID? Pourriez-vous conserver les UUID et simplement utiliser un auto-incrément comme clé primaire? –

+3

@ThomSmith Re "Les UUID ne sont pas des clés primaires très efficaces" ... tiens à citer une source qui explique pourquoi? – Pacerier

+1

C'est une donnée plus importante, et il faudra généralement plus d'instructions pour comparer. Ce n'est pas séquentiel, donc l'overhead de l'indexation est juste un peu plus élevé. Et, bien sûr, si vous le stockez comme une chaîne au lieu d'un numéro de 128 bits, comme le OP semble le faire, la situation s'aggrave. Ce n'est pas une clé terrible, mais je ne l'utiliserais pas à moins qu'il y ait une raison externe de le faire. –

Répondre

99

Si je comprends bien, vous utilisez des UUID dans votre colonne principale? Les gens diront qu'une clé primaire régulière (entière) sera plus rapide, mais il y a une autre façon d'utiliser le côté obscur de MySQL. En fait, MySQL utilise plus rapidement les binaires que toute autre chose lorsque des index sont requis.

Étant donné que l'UUID est de 128 bits et qu'il est écrit en hexadécimal, il est très facile d'accélérer et de stocker l'UUID.

D'abord, dans votre langage de programmation supprimer les tirets

De 110E8400-E29B-11D4-A716-446655440000-110E8400E29B11D4A716446655440000.

Maintenant c'est 32 caractères (comme un hachage MD5, avec lequel cela fonctionne aussi).

Puisqu'un seul BINARY dans MySQL a une taille de 8 bits, BINARY(16) est la taille d'un UUID (8 * 16 = 128).

Vous pouvez insérer à l'aide:

INSERT INTO Table (FieldBin) VALUES (UNHEX("110E8400E29B11D4A716446655440000"))

et requête en utilisant:

SELECT HEX(FieldBin) AS FieldBin FROM Table

Maintenant, dans votre langage de programmation, ré-insérer les tirets aux positions 9, 14, 19 et 24 pour correspondre à votre UUID d'origine. Si les positions sont toujours différentes, vous pouvez stocker cette information dans un deuxième champ.

Exemple complet:

CREATE TABLE `test_table` (
    `field_binary` BINARY(16) NULL , 
    PRIMARY KEY ( `field_binary`) 
) ENGINE = INNODB ; 

INSERT INTO `test_table` (
    `field_binary` 
) 
VALUES (
    UNHEX( '110E8400E29B11D4A716446655440000') 
); 

SELECT HEX(field_binary) AS field_binary FROM `test_table` 

Si vous souhaitez utiliser cette technique avec une chaîne hexagonale, toujours faire length/2 pour la longueur du champ. Donc pour un sha512, le champ serait BINARY (64) car un encodage sha512 fait 128 caractères.

+0

utiliser la fonction unhex rendre le résultat illisible. – Chamnap

+0

@Chamnap La fonction UNHEX convertira HEX en BINARY dans votre base de données. Vous pouvez ensuite utiliser des index dessus sans problème et avec un gain de performance (oui oui!). Vous lisez ensuite les données avec la fonction 'HEX' comme dans mon exemple. Donc non, vous ne pouvez pas lire le résultat de 'UNHEX', mais vous pouvez utiliser' HEX'. Rappelez-vous que l'ordinateur est fait de binaire, toujours plus rapide. –

+3

@Chamnap Disons que vous avez 10 000 lignes dans votre base de données et qu'elles ont été ajoutées en utilisant la fonction UNHEX et que vous voulez rechercher l'UUID '110E8400-E29B-11D4-A716-446655440000'. Faites simplement quelque chose comme: 'SELECT * FROM test_table WHERE field_binary COMME CONCAT ("% ", UNHEX ('110E8400E29B11D4A716446655440000'),"% ")' –

0

Je ne pense pas que ce soit une bonne idée d'utiliser un binaire.

Disons que vous voulez interroger une certaine valeur:

SELECT HEX(field_binary) AS field_binary FROM `test_table` 

Si nous revenions plusieurs valeurs alors nous appelons la fonction HEX plusieurs fois.

Cependant, le principal problème est la suivante:

SELECT * FROM `test_table` 
    where field_binary=UNHEX('110E8400E29B11D4A716446655440000') 

Et en utilisant une fonction à l'intérieur du où, ne tient pas simplement l'indice.

également

SELECT * FROM `test_table` 
    where field_binary=x'[email protected]#*#(&#@$9' 

pourrait conduit à de nombreux problèmes.

Questions connexes