【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-f92981b33be1cO+R6kfIRge66/kpgbM74Q==な感じに。

これで'36文字24文字になったので、12文字減りました

ここから最後の==のパディングはなくても問題ないものなので削除すればcO+R6kfIRge66/kpgbM74Q22文字まで圧縮できます。 可逆圧縮なのでデコードすればもとの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から戻せたところでなんのメリットがあるのかわからないのでハナから不可逆圧縮でいいかなと

コメント
※コメントは承認制となっていますので、コメントを頂いても直ぐには表示されません。
※不適切な内容(スパムや悪意ある内容等)のコメントは公開されませんので、ご了承ください。
※返信が必要な場合などでコメントの公開を通知されたい場合はメールアドレスの入力をお願いします。
名もなき名無しさん
メールアドレス(例:コメントの公開通知が欲しい場合)
内容