2012-06-08 10 views
71

UUID performance in MySQL numaralı sorunun cevabına göre, cevaplayan kişi UUID'yi bir dizi olarak değil, bir sayı olarak kaydetmeyi önerir. Nasıl yapılabileceğinden pek emin değilim. Bana bir şey önerebilecek olan var mı? Ruby'm kodum bununla nasıl baş ediyor?Uuid sayı olarak nasıl saklanır?

+5

Performans sorunları yalnızca UUID bir birincil anahtarı kullandığınızda ortaya çıkar, çünkü UUID'ler çok etkili birincil anahtarlar değildir. Neden UUID'lere ihtiyacınız var? UUID'leri saklayabilir ve sadece birincil anahtar olarak bir otomatik tekrarlama kullanabilir misiniz? –

+3

@ThomSmith Re "UUID'ler çok etkili olmayan birincil anahtarlar" değil. Nedenini açıklayan bir kaynaktan alıntı yapmayı önemsiyor musunuz? – Pacerier

+1

Daha büyük bir veri parçası ve genellikle karşılaştırmak için daha fazla talimat alacaktır. Sıralı değil, bu yüzden indeksleme yükü biraz daha yüksek. Ve tabii ki, eğer bunu yapmakta olduğu gibi, 128-bitlik bir sayı yerine bir dizge olarak saklıyorsanız, durum daha da kötüleşiyor. Bu çok önemli bir anahtar değil, ancak bunu yapmak için bir dış neden olmadıkça kullanamazdım. –

cevap

99

Doğru anlıyorsam, ana sütunda UUID kullanıyorsunuz? İnsanlar düzenli (tamsayı) bir birincil anahtarın daha hızlı olacağını söyleyecekler, fakat MySQL'in karanlık tarafını kullanmanın başka bir yolu var. Aslında, MySQL, indeksler gerekli olduğunda ikiliden daha hızlıdır.

UUID 128 bit olduğundan ve onaltılık olarak yazıldığından UUID'yi hızlandırmak ve depolamak çok kolaydır.

Öncelikle, programlama dilinde 110E8400E29B11D4A716446655440000 için 110E8400-E29B-11D4-A716-446655440000 itibaren tire

kaldırın.

Artık 32 karakterlik (bu, aynı zamanda çalıştığı bir MD5 hash gibi).

MySQL'deki tek bir BINARY boyutu 8 bit boyutunda olduğundan, BINARY(16) bir UUID'nin boyutudur (8 * 16 = 128).

kullanarak ekleyebilirsiniz:

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

ve sorgu kullanarak: programlama dilinde Şimdi

SELECT HEX(FieldBin) AS FieldBin FROM Table

, pozisyonları 9, 14, 19 at tire yeniden takın ve orijinal UUID'nizi eşleştirmek için 24. Eğer pozisyonlar her zaman farklıysa, bu bilgiyi ikinci bir alanda saklayabilirsiniz.

için tam bir örnek:

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` 

herhangi onaltılık dize ile bu tekniği kullanmak istiyorsanız

, her zaman saha uzunluğu için length/2 yapmak. Yani bir sha512 için, sha512 kodlaması 128 karakter uzunluğunda olduğundan alan BINARY (64) olacaktır.

+0

unhex işlevini kullanarak sonucu insan okunamaz hale getirir. – Chamnap

+0

@Chamnap UNHEX işlevi, veritabanınızdaki HEX'i BINARY'e dönüştürecektir. Ardından dizinleri problemsiz ve performans artışıyla kullanabilirsiniz (evet evet!). Daha sonra, örneğimde bulunan "HEX" işleviyle verileri okuyorsunuz. Yani hayır, sonucu 'UNHEX'den okuyamazsınız, fakat eğer' HEX' kullanırsanız yapabilirsiniz. Bilgisayarın her zaman daha hızlı ikili olduğunu unutmayın. –

+3

@Chamnap Veritabanınızda 10 000 satır bulunduğunu ve UNHEX işlevini kullanarak eklendiğini ve UUID '110E8400-E29B-11D4-A716-446655440000''ü aramak istediğinizi varsayalım. Sadece bir şey yapın: SELECT * test_table WHERE alan_binary LIKE CONCAT ("%", UNHEX ('110E8400E29B11D4A716446655440000'), "%") –

0

Bunun bir ikili kullanmak için iyi bir fikir olduğunu sanmıyorum.

Diyelim ki bazı değerini sorgulamak istiyorum varsayalım:

SELECT HEX(field_binary) AS field_binary FROM `test_table` 

biz o zaman HEX fonksiyonu birkaç kez aradığınız birden fazla değer iade ediyorsanız.

Ancak asıl sorun sonraki biridir:

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

Ve yerde içinde bir fonksiyonu kullanılarak, sadece endeksi dikkate almaz.

Ayrıca

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

Olabilir birçok sorunlarına yol açar.