はじめに、筆者はフロントエンドエンジニアです。 なので細かい知識などはないです。
【PostgreSQL】短いUUIDをdefault valueに設定する方法【base64】
まえがき
さて、テーブルのIDにはオートインクリメント(自動採番)
、UUID
などがあり、前者はDB側でinsert時に制御したり、後者ならDBでの制御や利用側で生成したユニークキーを使用するなどがあると思います。
ただUUID(v4)って長いんですよね。
たとえば 70ef91ea-47c8-4607-baeb-f92981b33be1
な感じでとても長いです。
それもそのはずで、uuidは128bit
で表現され、文字数にすると36文字
になります。
なのでよくbase64に変換して使うケースも多いのではないでしょうか?
70ef91ea-47c8-4607-baeb-f92981b33be1
→cO+R6kfIRge66/kpgbM74Q==
な感じに。
これで'36文字
→24文字
になったので、12文字
減りました
ここから最後の==
のパディングはなくても問題ないものなので削除すればcO+R6kfIRge66/kpgbM74Q
の22文字
まで圧縮できます。
可逆圧縮なのでデコードすればもとのUUIDにも戻せます。
もし必要であれば+
と/
も省けばその分文字数は減らせますが、その代わりに不可逆圧縮となってしまうため、元のUUIDには戻せなくなります。
また、+
や/
はURLにも使われるものなので、URLにIDを表示する場合は適宜URLエンコードをかけるなどの処理が必要になります。
(+
/
を除いたbase62みたいなものがあればいいんですが、ないん……あるのか。なんで普及しないんや……)
本題
さて、本題です。 base64で変換をすればある程度短くなるというのはわかりました。 ただinsert処理を使う箇所に毎回idを設定するのは正直面倒なので、primary keyとなるIDなどは基本的にはDB側のdefault valueで値を設定したいです。
ただしMySQLはそもそもUUID自体、defaultで入れるにはちょっと小細工が必要そうなので、今回はPostgreSQLに関してのお話になります。
PostgreSQLにはuuid-ossp
というエクステンションを導入しているとuuid_generate_v4()
メソッドを使用できるようになり、これをdefault値として使用することでUUIDで自動的にIDが作られます。
これはtext型
varchar型
uuid型
いずれも機能します(てかuuid型なんてあるんだ。MySQLユーザーだったから初めて知った)
またどうやら他のメソッドなどもdefault値に使えるようで、encode(uuid_send(uuid_generate_v4()),'base64')
のように設定するとUUIDをbase64に変換したものが自動的に登録されるようになります。(ただしbase64に変換する場合はuuid型は不可)
マジ便利(MySQLにも欲しい)
あとは==
のパディングを削ればいいので、最終的にはreplace(encode(uuid_send(uuid_generate_v4()),'base64'),'==','')
とすればパディングを省いたbase64が自動的に登録されます。
Happy.
余談
ちなみにですが、個人でなにか作る分には好きにできるので、基本的には不可逆圧縮で+
/
も省いたreplace(replace(replace(encode(uuid_send(uuid_generate_v4()),'base64'),'==',''),'+',''),'/','')
で設定します。
これでなんの処理をしなくてもURLに設定しても問題なくなります(https://example.com/posts/cOR6kfIRge66kpgbM74Q
みたいに)
UUIDのメリットって基本的には衝突が発生しないってことだと思っていて、base64から戻せたところでなんのメリットがあるのかわからないのでハナから不可逆圧縮でいいかなと