前提
(Rails + )MySQLでのID(主キー)とUIDの良い設計方法が知りたい。
usersはID(主キー)カラムとUIDカラムを持つとします。
「あなたのユーザーIDは#{user.uid}です」、のように使われるものとし、IDはユーザが意識することはありません。
主キーは1からオートインクリメントされます。
ユーザーIDは、他の全ユーザーのユーザーIDのうち最も大きいもの+ランダム値(11〜20)とする。(15,26,43,…)(最初uid=1のユーザーがいるものとしていいです)
実現したいこと
どのように設計するのがベストなのかが知りたいです。
試したこと
まず一番やりたい方法はIDカラムをユーザーIDのような方法で作成することです。
調べましたが、MySQLにおいて、オートインクリメントの値をランダムに設定することはできませんでした。
ですのでRails側で解決しようと思いました。
案1
ruby
1ActiveRecord::Base.transaction do 2 # 略 3 current_max_uid = User.last.uid 4 new_user = User.new(uid: current_max_uid + 10 + rand(10)) 5 new_user.save! 6 # 略 7end
とするのが良いのかと思いましたが、同時にこの処理をしたユーザーが他にいた場合、User.last.uidが同じになってしまう可能性があり、uidも同じになってしまう可能性が出てしまいます。
案2
ruby
1ActiveRecord::Base.transaction do 2 # 略 3 user = User.new.save! 4 current_max_uid = User.find(idがuser.idより小さいものの中で一番大きいもの).uid 5 user.uid = current_max_uid + 10 + rand(10) 6 user.save! 7 # 略 8end
のような方法も思いつきましたが、2回セーブするのは微妙だと感じました。
案3
ruby
1ActiveRecord::Base.transaction do 2 # 略 3 # users.uidカラムの代わりにusers.randomカラムがある 4 new_user = User.new(random: 10 + rand(10)) 5 new_user.save! 6 # 略 7end 8 9Class User 10 def uid 11 User.where(id: ...id).pluck(:random).sum 12 end 13end
のような方法もあると思いますが、表示のたびに全ユーザーをセレクトするのはなさそうです。
どの方法を取るのがいいでしょうか。それとも他にいい方法がありますか。ボールドテキスト
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。