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

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

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

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

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

Q&A

2回答

8324閲覧

カラム数が多すぎるテーブルの1対1関連での分割方法

yamasho

総合スコア12

Ruby on Rails

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

データベース設計

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

0グッド

0クリップ

投稿2016/04/20 15:03

お世話になります。

カラム数が200を超えるテーブルを複数扱う案件を受け持ちました。
実際のテーブル情報などは載せれないので似た例としてゲームの情報を扱うテーブルがあったとします。
今回は簡単ですが、このgenreについてもそれぞれたくさんの情報があると50を超えるカラムがあると考えてください。
元のテーブル

私が考える構成は以下のようなものです。
分割後
game_information_genres、game_information_makersそれぞれにも50を超えるカラムがあるとします。

以下のようにgame_informationsテーブルでまとめなくても良いとは思うのですが、game_information_genres、game_information_makersのデータを一度にまとめて取得したいと言った時に簡単に取得できるので中間テーブル?としてgame_informationsテーブルも設置しました。
イメージ説明

この構成(2つ目の画像)は良い設計と言えるでしょうか?

私はこの構成だと以下の問題を持つと考えています。

  • テーブル名が長くなりすぎる
  • それに伴って、関連キーのカラム名が長くなりすぎる
  • SQL実行1回のコストが高くなる

しかし、メリットとして

  • 情報が視覚的に分かりやすくなる
  • 情報取得コードがシンプルになる(ActiveRecord)
  • 構成の変更がしやすい

もあげれるのではないかと考えています。

非常にカラム数が多くカオスで、今後の保守・開発がスムーズに進むようにもっとも望ましい形にしたいと考えています。
皆様のお力を貸していただきたいです。
どうぞよろしくお願い致します。

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

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

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

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

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

guest

回答2

0

良い設計ではないです。

200を超えるカラム数というのは確かに分割する要素はあるのかもしれませんね。
テーブル設計の変更に対しては、正規化の観点でよりよい設計とならないか検討してみてください。
この時、求められる処理と正規化のレベルに注意してください。それが正しい設計につながります。

良い設計ではないとした理由は、保守・開発がスムーズに進むことを目的としているからです。
yamashoさんにとっては求めている回答と少しずれた回答かもしれませんね。
説明します。

テーブル設計として良否を決定するものは"性能"です。テーブル設計としてカラム数が設計の良否を決定づけるものではありません。システムの利用者にとって性能は絶対的評価基準で、処理が遅いシステムはそれだけで悪とみなされます。データベースはシステムの性能の核になります。テーブル設計は最も性能が出るよう努力されたものであることが求められます。

yamashoさんも「SQL実行1回のコストが高くなる」と性能に悪影響があることは想定されています。これは正しいです。「今後の保守・開発がスムーズに進む」この気持ちすごくわかります。ですが、メリットに書かれた内容に利用者にとってのメリットはあるでしょうか。私には我々開発者がよくやる開発側の論理にに見えました。やってしまった結果性能が落ちトータルで悪い結果につながるオチがつくパターンです。

正規化に取り組んでみてください。もしかしたら結果として200カラムを超えるテーブルが出来上がるかもしれません。もしそうなったら、200カラムを超えるテーブルは正しいテーブル設計であったと言えます。

Railsで実装するにあたって200カラムのレコードなんてと思う気持ちわかります。
が、ORマッピング分野においてこの手の話は最適解がない課題なんですよね。。。
極論的には"この部分だけは"フレームワークのORマッピング(RailsのActiveRecord)は使わず自前のORマッピングを用意して捌くと思います。
yamashoさんの構成イメージにある genre と maker を 200カラムレコードの該当カラム使ってObjectにMappingするORマップ処理を自前で作るイメージです。

投稿2016/04/23 15:09

編集2016/04/23 15:14
Hiroshi-Aoki

総合スコア804

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

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

0

カラム数が200を超えるテーブルを複数扱う案件

既に”動いている”という事でしょうか。
であれば、「そのまま」にして、修正は必要最低限に抑えます。
それと、「ゲーム」「ジャンル」「メーカー」を別テーブルに持つか?については、
断片化を考慮した更新頻度、画面設計、性能設計など、様々な要因で決めます。

今回はゲーム名・ジャンル・メーカーが例えなので、
更新(削除)頻度はそこまでないと考えると、
1:1のカラムについて、動いているものをわざわざ分けたりはしない。
カラム名に工夫をしてあげれば、見やすくはなるかと思いますが、カラム名の変更もしない。
テーブル仕様が存在しない場合、カラム名に対するコメントの付与が限界です。

適切なINDEXが貼ってない事が原因で性能劣化があるのであれば
適切なINDEXを付与するだけで、200カラム以上のままの設計にしますね。

ただし、ゲーム名が毎月のように全データが削除・登録されるような要件で、かつ、
ある程度の件数があれば、数か月後には性能劣化する事が明らかなので、
テーブルを分けて、断片化するテーブルとしないテーブルを分けたりするかもしれませんが。
緊急性がない限り、動いているままにする方が良いと思います。

この構成(2つ目の画像)は良い設計と言えるでしょうか?

今回の例(ゲームの例え、かつ、1つのテーブルを1:1に分ける場合)では、
どちらも良い設計ではないかな。

「game_information」テーブルがある方の設計は初期段階であれば、まだ良いですが、gamesとgames_informationを分ける必要性が見当たりません。

「game_information」テーブルがない方の設計はgenre VARCHAR(45)で紐づけするようですが、
VARCHAR(45)もの長さで紐づけするのはあまり良くない設計です。

せめてgenre_id int、maker_id intによる紐づけが良いですが、これは、マスター化する場合の設計なので、今回の"分割"とは違うような。

なお、純粋に分割がありかなしか、を問うのであれば、
games テーブルにある内容を以下の3つに分けて、
game_idで紐づけられるようにするのはありか?となると思います。

games(id,name…)
games_genres(game_id,genre…)
games_makers(game_id,maker…)

この設計がアリかナシかは「…」の中身と全体の仕様次第です。

投稿2016/08/28 19:13

tomari_perform

総合スコア760

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問