質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

Q&A

2回答

403閲覧

ユーザー間の値の差分がランダムになるようなユーザーIDを実装したい

nagiro

総合スコア0

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 6

Ruby on Rails 6は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース設計

データベース設計はデータベースの論理的や物理的な部分を特定する工程です。

0グッド

2クリップ

投稿2022/08/04 10:57

前提

(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

のような方法もあると思いますが、表示のたびに全ユーザーをセレクトするのはなさそうです。

どの方法を取るのがいいでしょうか。それとも他にいい方法がありますか。ボールドテキスト

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

uid に unique index を付けましょう。
それが トランザクション にも有効|必要かも

投稿2022/08/04 22:48

winterboum

総合スコア23284

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

同時にこの処理をしたユーザーが他にいた場合

それこそ、トランザクションの出番ではないでしょうか。

投稿2022/08/04 11:11

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問