web-dev-qa-db-ja.com

uuidを数値として保存する方法は?

質問の答え MySQLでのUUIDパフォーマンス に基づいて、答える人はUUIDを文字列としてではなく数字として保存することを提案します。どうやってそれができるのかよくわかりません。誰かが私に何かを提案できますか?どのように私のRubyコードはそれを扱いますか?

74
Chamnap

私が正しく理解している場合、プライマリ列でUUIDを使用していますか?通常の(整数の)主キーが高速になると人々は言うでしょうが、MySQLのダークサイドを使用する別の方法があります。実際、インデックスが必要な場合、MySQLはバイナリを使用するよりも高速です。

UUIDは128ビットであり、16進数として記述されているため、UUIDの高速化と保存は非常に簡単です。

まず、プログラミング言語でダッシュを削除します

_110E8400-E29B-11D4-A716-446655440000_から_110E8400E29B11D4A716446655440000_へ。

現在は32文字です(MD5ハッシュのように、これも機能します)。

MySQLの単一のBINARYのサイズは8ビットなので、BINARY(16)はUUIDのサイズです(8 * 16 = 128)。

次を使用して挿入できます。

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

および使用するクエリ:

SELECT HEX(FieldBin) AS FieldBin FROM Table

プログラミング言語で、元のUUIDと一致するように、9、14、19、および24の位置にダッシュを再挿入します。位置が常に異なる場合は、その情報を2番目のフィールドに保存できます。

完全な例:

_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`
_

16進文字列でこの手法を使用する場合は、フィールド長に対して常に_length / 2_を実行します。したがって、sha512のエンコードは128文字なので、sha512の場合、フィールドはBINARY (64)になります。

106
David Bélanger

Perconaブログには、あなたの質問に答える記事(ベンチマークを含む)があります: IDを最適化された方法で保存する

8
dolmen

バイナリを使用するのは良い考えだとは思いません。

何らかの値をクエリしたいとしましょう:

SELECT HEX(field_binary) AS field_binary FROM `test_table`

複数の値を返す場合、HEX関数を数回呼び出しています。

ただし、主な問題は次の問題です。

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

また、where内で関数を使用すると、単純にインデックスが無視されます。

また

SELECT * FROM `test_table`
    where field_binary=x'skdsdfk5rtirfdcv@#*#(&#@$9' 

多くの問題につながる可能性があります。

0
magallanes