PV0お世話になります。カラム数が200を超えるテーブルを複数扱う案件を受け持ちました。あまりにも一つのテーブルにカラムが多すぎて、情報の場所やカラム名を見つけるのが大変なため、テーブルを分けたいと考えています。実際のテーブル情報などは載せれないので似た例としてゲームの情報を扱うテーブルがあったとします。今回は簡単ですが、このgenreについてもそれぞれたくさんの情報があると50を超えるカラムがあると考えてください。私が考える構成は以下のようなものです。game_information_genres、game_information_makersそれぞれにも50を超えるカラムがあるとします。以下のようにgame_informationsテーブルでまとめなくても良いとは思うのですが、game_information_genres、game_information_makersのデータを一度にまとめて取得したいと言った時に簡単に取得できるので中間テーブル?としてgame_informationsテーブルも設置しました。この構成(2つ目の画像)は良い設計と言えるでしょうか?私はこの構成だと以下の問題を持つと考えています。あげれるのではないかと考えています。非常にカラム数が多くカオスで、今後の保守・開発がスムーズに進むようにもっとも望ましい形にしたいと考えています。皆様のお力を貸していただきたいです。更新順0返信が遅くなりすみません。その方向で回答します。垂直分割自体は悪ではないですが(この構造ならそこまでやるなら正規化したほうが良いとは思いますが)、N+1問題は気を付けたほうが良いでしょう。loadingするにも毎度全て収集するのかといったバランスも考えないとダメかもしれません。あとはstatusの全てが外にあったほうが良いのか(itemに常に必要とされるstatusはないのか)といった部分は整理されたほうがいいと思います。最初の回答にも書きましたが誰にとって良い設計なのかも考えておくといいと思います。モデルだけを扱うだけで良い(DBは意識しない)から、追加のSQLを気にしなくて良いから、DB構造が綺麗になるからか、インデックスのコスト、インポート容易性などいくつかの視点があると思いますが、全てをクリアできない時にどれを優先するのかは考えておくといいと思います。コード上の見渡し(ミスの軽減)を目的としているという記述は見受けられましたが、モデル直接扱わずに間に薄い層を設けたり、テストコードで解決する手もあるでしょう。DB保守の面で言えば後述しますが図にもいくつか疑問があります。簡単にでも行っておいた方が良いとは思います。分割するだけにならないように注意して設計してください。視点が違えば優劣のつけ方も変わってくると思います。どちらが目的に適しているかで選択されると良いでしょう。以下は追加の回答で提示していただいた図を見ての疑問点です。重箱の隅をつくような話なので、本題と関係なさそうであれば特に回答はなくて問題ありません。2番目、3番目の図の話です。1:1のままではないか。これは列を行にするつもりだったということでしょうか。item_statuses_idがあるが関連としては逆では?(双方向に関連させるのでしょうか)図にしてくれたのはありがたかったですが、部分的に疑問に思うことがあったためいくつか混んらんしてしまいました。idと論理的に同じはずであり、手動で設計した場合は発生しない列です。テーブルを管理する上では冗長な情報であるのでDBだけを見た場合のためにどこかに明示しておいたほうが良いでしょう。item_statusesを主としてitemsにアクセスすることができます。これが許容できるのか(スタイルの一貫性などで問題とならないか)も考えたほうが良いでしょう。さん丁寧なご回答ありがとうございます。やりたかったことはgames-ext-infoです。こちらの状況と私が提示した例が悪く、説明も不十分でした。新しく例を作ってみたのですが、のようにすべてのstatusはitem一つ一つ違ったもので、そのstatusには様々な情報のtypeがあるとします。これらのstatusはtypeごとに20近いカラムがあり、typeは6以上あるとします。それぞれのtypeには一つのitemが複数持つことがあるデータ(type1を3つなど、1対多)、一つしか持たないデータ(1対1)があります。そのため、単純にのようにしてしまうと、status_type1_hogeなどのtypeは分かれているけれどデータは一つなので1対多関連のstatus_type1s、status_type2sには含めれないということが起きます。itemsはstatus以外にもたくさんのカラムを持っているため、status_type1_hogeなどの情報だけitemsテーブルにあると開発時に見落としが発生するなど問題が発生してしまいそうです。そのため、せめてitem_statusでまとめようということで、以下のようにitem_statusesテーブルを作ろうかと思いました。ここで、item_status_type4....がitem_status_idを持つ理由は、ItemStatusがItemStatusType4....をhas_oneする関係にあるため、itemのidでitem_statusを探し、item_status_idでitem_status_type4....を探し取得するように考えています。この場合ですと、2つ目と3つ目の画像でどちらが良いでしょうか?どうぞよろしくお願いいたします。itemを特定できなくなると思うのですが。status_type1_c2_3.......のようにカラムが存在しています。item.item_status_type1s```のようにしようと考えています。02:272実際のデータはわかりませんのでそれを抜きにして提示された情報で感じた印象ですが、game_informationsテーブルの役割がよくわかりません。gamesにはゲーム固有の情報の一部(メーカーやジャンルにまつわる情報以外)が入るのでしょうか。gamesのidは、game_informationsのgame_idと紐づくわけですね。game_informationsはgame_idを持たないといけないので、仮に同ジャンルを同じメーカーから発売していてもgame_idの数より少なくなることはできません。これはこのテーブルがあくまでゲーム固有の情報の一部を垂直分割しただけのテーブルなのでいいということなのでしょう。game_information_makersはgame_information_idを持つのでgame_information_idより少なくなることはできません。gamesと少なくとも同じ件数になるわけですね、分割前を考えれば同じ件数ということでしょうか。いうことは、game_information_makers.idとはgames.idの別称ともいえるわけでgame_information_idではなくgames_idを持っても同じことになるような気がします。game_informationsにどういう情報を持たせるのかにもよってくるのですがgame_informationsにはgamesとそれ以外のテーブルを紐づけるためのキー情報しか持たないこの場合はテーブルが増えるだけでgame_informationsは分割に寄与していません。game_informations.idとgame_informations.game_idが同じ値でも成り立ってしまうからです。game_informationsはキー以外に実データも含むこの場合を突き詰めていくとgamesテーブルはidだけでよくなります。idしか持たないテーブルが有用かどうかは説明するまでもないと思います。gamesとgame_informationsのいずれかは不要な表ではないかと感じました。ここで、3番目の画像を見てみると、gamesはジャンルとメーカーを持っていますね、これはジャンルとメーカーのキーを持っていてそれをつかってジャンルやメーカーの情報を取得しにいく単純な正規化の話でしょう。ジャンルやメーカーはゲームのidに紐づく情報を持っていません。2番目の画像を見てみるとジャンルやメーカーがゲームに紐づくための情報を持っていることがわかります。game_information_makersという探索方向に変わっているということです。新規に設計した場合ならば、メーカーよりもゲームの方が多いと思いますので、主キーが重複してしまうことになるでしょう。いうことで2番目の設計はよくないと思います。idなんだか日付なんだかもパッと見でわからない状態で不満が残ったとする。genre-kana(makerやgenreが正規化できたとして、中間テーブル作るとさっきと同じものができると思います)がごっちゃになったんじゃないでしょうか。現状で分割することばかりに意識がとられていて概念設計(データベースを抜きにして、データにはどういう実体が存在しているのか、どういう関連なのかの整理)や論理設計が不十分な状態で物理設計にはいっているような印象があります。(やっていたらごめんなさい)この手の状況はメインフレームのデータをRDBに落とし込むときによく見かける気がしますが、この手のデータで気になるのはデータの質といいますか正規化が可能な状態にあるかですね。選択された値が基本であれば、ユーザーによるばらつきがない個所はマスタデータなどに分離して一部のデータはキーで管理することができます。項目はわかれてはいるが入力者が思うがままに入力可能だったり、「xx年より前はカナしかなくxx年より後は漢字しかない(そして古いデータのメンテもされない)」といったばらつきがあれば同じ件数のテーブルに分ける(垂直に分割する)しかできません。この場合は中間テーブルを作ったところで基本的に分割前のキーを複数持つだけなのでその意味合いは薄くなるように思います。1つのゲームを複数の会社が共同で作るから複数登録したいと言われた場合にどうするかですね。「構成の変更がしやすい」には反するかと思います。一部の情報だけ選択したい場合に不要なキー情報がたくさんついてくるのも気になりますね。中間テーブルがシンプルでない(複数の関係情報を持つ)のでActiveRecord(パターン?Rubyの方?)に頼った場合はコストが心配になります。すべてのケースに対応するのは不可能ですし、仮定の話ですが様々なことを予想しておくのは大事だと思います(実装に盛り込む必要はないですが)。「情報が視覚的に分かりやすくなる」は「誰」が「どんなときに」分かりやすいのかまで考えるといいと思います。求めていた回答とはちがうかもしれませんが長々と失礼しました。さん、丁寧なご回答ありがとうございます。画像を使いたいため、回答として返信差し上げましたのでご回答いただけたら幸いです。16:03ウォッチこの質問への回答やコメントをメールでお知らせします。