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

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

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

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

Q&A

2回答

2349閲覧

[Ruby on Rails] JOINしたテーブルの値での並び替えを高速化するには?

namenamenameko

総合スコア234

Ruby

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

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Ruby on Rails

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

Active Record

Active Recordは、一つのオブジェクトに対しドメインのロジックとストレージの抽象性を結合するデザインパターンです。

0グッド

0クリップ

投稿2017/11/01 08:12

編集2022/01/12 10:55

データベースに関して初学者のため、意味不明な点があればご指摘をお願いいたします。

開発しているシステムにて以下のような構造が存在します(例のためモデル名は変えています)。

モデル

Player: 人のデータ Rank: Playerのレベルを表すマスタデータのテーブル、R1~R5まであり、その説明なども記録されている PlayerRank: PlayerとRankの関連を表すモデル (PlayerのRankは、実務上最初に与えられたランクから変更されることはほぼありません。)

という内容で、

Player has_one PlayerRank PlayerRank belongs_to Player PlayerRank belongs_to Rank

というアソシエーションがあります(わかりづらかったらすみません、、)。

ここで、Player一覧において、Player.allをR1R5で並び替えが行われる機能を実装したいと考えています。
しかしながら、R1
R5はRankのカラムであるため、

Ruby

1Player.preload(:player_rank)

のようにしなければ、Player.allを並び替えできないと思います(内部的には、テーブルを結合しているということですよね?)。
このpreloadのクエリが、結果をキャッシュしているようですがPlayerの件数が多いため非常に時間がかかり、現実的に並び替えの機能を実装できない状態になっています(Player一件ずつに対してキャッシュの処理が走る?)。

以上に関して、どのようなアプローチを取れば良いかご教授願えないでしょうか。
おそらく色々間違っていると思うのですが、設計の間違いか、クエリのとりかたの間違いなのか、包括的にご指摘願えれば幸いです。

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

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

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

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

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

guest

回答2

0

もともと、「ランク1~5」のような少ないものでソートする場合、インデックスがあまり役に立たないので、「一時表で並べ替え」しか取れる手段がありません。

逆に、ランクが5つしかないのであれば、「ランク1のプレイヤーを探す」「ランク2」…「ランク5」というように引いていって、その5つの結果を組み合わせるようにしたほうが効率的ではないかと思います(もちろん、書くべきコードは山のようになりますが)。

…というより、各プレイヤーが1つのランクにしか属さないのなら、Player belongs_to :rankとして、中間テーブルを廃してしまったほうがスッキリするかと思います。

投稿2017/11/01 08:23

maisumakun

総合スコア145121

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

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

namenamenameko

2017/11/01 08:31

ご回答ありがとうございます。 「一時表」について存じ上げなかったのですが、こちらはJOINした結果を保存しておくようなものなのでしょうか? 中間テーブルについては、上の方の意向でこのようになったのですが、、(正規化?) 「preloadの処理自体を高速化する」方法がないということでしたら、それを確認することができて幸いです。
namenamenameko

2017/11/01 08:40

ちなみに、プレイヤーに割り当てられたRankですが、実際には最初に設定された値でほぼ変化することはありません。
guest

0

PlayerRank

idplayer_idrank_id
115
221
333
442
554

Player

idneme
1ほげ
2ふが
3ふご
4んが
5ンゴ

Rank

idnamedescription
1R11位
2R22位
3R33位
4R44位
5R55位

HTML

1ふが 2んが 3ふご 4ンゴ 5ほげ

投稿2017/11/01 10:39

編集2017/11/03 05:49
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

namenamenameko

2017/11/02 07:02

ありがとうございます。 設計については、認識の齟齬は内容に思われます。 (ただしRank has_one :PlayerRankのアソシエーションに関してはあえて使わないのでつけてないですが) > また、このPlayerRankテーブルには player_id rank_id この2つのIDが存在しているということでしょうか? こちらはその通りです。 > またRankに存在するカラムの名前と値を教えてください。 id, name(string), description(string)です。 nameは「R1」〜「R5」までの文字列(こちらは実際にはidで判別しています)、 descriptionは、それぞれのレベルの目安的なものを表す説明文で、数十文字といったところです。
退会済みユーザー

退会済みユーザー

2017/11/03 05:51

回答の方にテーブル構造を追記しました。 こちらの認識で合っているでしょか?また追加して欲しいカラム等はありませんでしょうか? HTMLには最終結果として出力される内容を書いていますがこちらでよろしいでしょうか?
namenamenameko

2017/11/03 08:42

はい、あっております。 ありがとうございます。
退会済みユーザー

退会済みユーザー

2017/11/03 11:01

このデータ構造だとまず、maisumakunさんが言っているように、PlayerRank中間テーブルは必要ありません。Playerテーブルにrank_idのカラムを作ります。 「正規化」というのであれば、「PlayerRank」テーブルには、「player_id:1」の「ほげ」さんが「1位」のデータもあるし「5位」の時のデータもある。というのが中間テーブルとしての正しい使い方です。 http://gomocool.net/gomokulog/?p=820 ですが上の意向で必要であるとおっしゃっていますので、このテーブル構成で話を進めますか? それとも削除したという過程で進めますか?
namenamenameko

2017/11/04 06:06

やはり必要なさそうですね・・・ もしよろしければ、削除しない場合でどのような対処が可能か教えていただければ幸いです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問