理由がわかりません
SELECT UUID();
次のようなものを返します。
3f06af63-a93c-11e4-9797-00505690773f
しかし、たとえばBEFORE INSERTトリガーを使用してbinary(16)フィールド(UUID()関数)に挿入し、selectを実行すると、次のような結果が返されます。
0782ef48-a439-11
これら2つのUUIDは同じデータではないことに注意してください。
バイナリとUUID文字列は同一に見えませんが、選択されたデータは少なくとも同じ長さであってはいけません。それ以外の場合、どのように等しく一意である可能性がありますか?
Char(36)として保存する方が良いですか?重複する挿入を防ぐために、一意である必要があります。結合に選択または使用されることはありません。
編集:
beforeトリガーは次のようになります。
BEGIN
if NEW.UUID IS NULL THEN
NEW.UUID = UUID();
END IF
END
だから、コメントへの応答として。 36文字のUUIDをbinary(16)として保存する正しい方法は、次のような方法で挿入を実行することです。
_INSERT INTO sometable (UUID) VALUES
(UNHEX(REPLACE("3f06af63-a93c-11e4-9797-00505690773f", "-","")))
_
UNHEX
。これは、UUIDがすでに16進数値であるためです。ステートメント内のダッシュをトリミング(REPLACE
)して、長さを32 ASCII文字(16バイトはHEX
として表されます)にします。これは、保存する前のどの時点でも、明らかに、データベースで処理する必要はありません。
次のようにUUIDを取得できます。
_SELECT HEX(UUID) FROM sometable;
_
誰かがこのスレッドに出くわし、これがどのように機能するかわからない場合に備えて。
そして覚えておいてください:UUIDを使用して行を選択している場合、条件でUNHEX()
を使用:
_SELECT * FROM sometable WHERE UUID = UNHEX('3f06af63a93c11e4979700505690773f');
_
列のHEX()
ではない:
_SELECT * FROM sometable WHERE HEX(UUID) = '3f06af63a93c11e4979700505690773f';
_
2番目の解決策は機能しますが、一致する行を判断する前に、MySQL HEX
esがすべてのUUIDを必要とします。非常に非効率的です。
編集:MySQL 8を使用している場合は、SlyDaveの回答に記載されているUUID関数をご覧ください。この答えは今でも正しいですが、これらの関数を使用してネイティブに実行できるUUIDインデックスを最適化しません。
MySQL 8では、2つの新しい ID関数 を使用できます。
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));
また、このメソッドは、UUIDの時間コンポーネントの再配置をサポートし、インデックスのパフォーマンスを向上させます(時系列に並べることにより)。2番目の引数をtrueに設定するだけです-これはUUID1でのみ機能します。
インデックスのパフォーマンスにUUID_TO_BIN
フラグにtrue
フラグを使用している場合(推奨)、BIN_TO_UUID
にも設定する必要があります。そうしないと、正しく変換されません。
詳細については、ドキュメントを参照してください。
他の答えは正しいです。 UUID()
関数は36文字の文字列を返し、表示されている関数(UNHEX()
、または新しいプラットフォームではUUID_TO_BIN()
)を使用して変換する必要があります。
ただし、独自のソフトウェアを使用してUUIDを作成する場合は、代わりに 16進数リテラル表記 を使用できます。
したがって、MySQL UUID()
関数で以下を使用します。
INSERT INTO sometable (id) VALUES (UNHEX(REPLACE(UUID(), '-', ''))); -- all versions
INSERT INTO sometable (id) VALUES (UUID_TO_BIN(UUID()); -- since v8.0
ただし、独自のUUIDを生成する場合はこれを使用します。
INSERT INTO sometable (id) VALUES 0x3f06af63a93c11e4979700505690773f;
同様に、WHERE
句で16進数リテラルを使用できます。
SELECT * FROM sometable WHERE id = 0x3f06af63a93c11e4979700505690773f;
データを毎回UUID文字列に変換する必要がない場合、これは高速になります。
注:'x'
in '0xaBc
は大文字と小文字が区別されます。ただし、16進数はそうではありません。
MariaDBを使用しているので、BIN_TO_UUID
関数ファミリは存在しません。とにかく対応する値を取得することができました。
bin -> hex
ここで、uuid
はuuidのbinary(16)値です。以下の値を使用して、読み取り可能なバージョンを選択します。
LOWER(CONCAT(
SUBSTR(HEX(uuid), 1, 8), '-',
SUBSTR(HEX(uuid), 9, 4), '-',
SUBSTR(HEX(uuid), 13, 4), '-',
SUBSTR(HEX(uuid), 17, 4), '-',
SUBSTR(HEX(uuid), 21)
))
hex -> bin
ここに、 cc6e6d97-5501-11e7-b2cb-ceedca613421
はUUIDの読み取り可能なバージョンであり、WHERE句で以下の値を使用して検索します。
UNHEX(REPLACE('cc6e6d97-5501-11e7-b2cb-ceedca613421', '-', ''))
乾杯