人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

MySQLの正規化・構造についての質問です。

A?Eまで5つの異なるカテゴリ用のテーブルがあるとします。
1つのカテゴリに対して、「基本情報」「アクセス情報」「コメント」など、
5つのテーブルが必要になるとします。
(その5つのテーブルには、10前後のフィールド数がある)

なので、テーブルは
A01、A02、A03、A04、A05
B01、B02、B03、B04、B05 ...
と言うように、5×5の25テーブルが必要になります。

1つのカテゴリのすべての情報を表示する時は、joinで結合して表示しようと思っているのですが、複数テーブルを結合しても処理速度に問題はないのか?PHPで操作するので、ややこしくならないか?UNIONを使って、Aに関するテーブルとBに関するテーブルを結合する時はどうなるのか?

など、設計を考えているだけでよくわからなくなってきます。
しかし、1カテゴリに付き100近くのフィールド数が必要なので、
テーブルを分けないと、効率的でない気もします。

そこで質問ですが、正規化しテーブル数が増えることにより、なにか処理や操作の面で後々問題になる事はありませんでしょうか?PHPで表示する時、扱いにくいとか。

ちなみに、MySQLは4.x系以降の考え方でお願いします。

●質問者: kt26
●カテゴリ:ウェブ制作
✍キーワード:MySQL PHP アクセス カテゴリ コメント
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● KUROX
●27ポイント

私ならという前提で回答します。

------------------------------------

MySQLのJOINはそこそこだという仮定をします。

情報ソースは以下のところ

http://itpro.nikkeibp.co.jp/article/NEWS/20070624/275673/

DB設計は基本、正規化した状態からの出発だと私は

思っています。

で、それぞれのデーブルでのレコード数とか

データアクセスパターンを予想して、最適化します。

>1カテゴリに付き100近くのフィールド数が必要なので、

>テーブルを分けないと、効率的でない気もします

正規化した後で、テーブルを分けないと効率が悪いと

判断すれば、テーブルを分けるべきです。

SQLで読むときは楽だけど、更新するときは難しいテーブル構造

とかは、それはそれでどうかなと思うときもあります。

バランスだと思います。

◎質問者からの返答

回答ありがとうございます。参考にさせていただきます。


2 ● chuken_kenkou
●27ポイント

A?Eまで5つの異なるカテゴリ用のテーブルがあるとします

カテゴリ毎にA?Eと、表を分ける理由は何でしょうか?

LOCK TABLEで特定のカテゴリの表を占有し、大量のデータを処理したいといったケースがあるのでしょうか?

カテゴリid等のキーを持ち、全カテゴリを1表に格納しても問題ないと思いますが?

インデクスはB-TREE構造なので、データ件数が5倍に増えても、インデクスを有効利用できる検索条件(=、範囲、前方一致など)を適切に使用すれば、極端に性能が落ちることはありません。


1つのカテゴリに対して、「基本情報」「アクセス情報」「コメント」など、

5つのテーブルが必要になるとします

この辺の事も、具体的に説明してもらえば、より適切なアドバイスができるかも知れません。

複数テーブルを結合しても処理速度に問題はないのか?

これは表やインデクス設計、結合方法などで、高性能を出せる場合もあれば、逆に性能を出せない場合も出て来ます。

PHPで操作するので、ややこしくならないか?

同一列名があった場合などは、「列名 as 別名」といった方法で、別名で一意に識別できるようにするのが一般的です。

UNIONを使って、Aに関するテーブルとBに関するテーブルを結合する時はどうなるのか?

unionを使えるということは、各カテゴリの「表の列構成は同じ」ということですから、最初に述べたように「カテゴリ毎に表を分割する必要性」が分かりません。

1カテゴリに付き100近くのフィールド数が必要

RDBMSでは、表の列数が増えると、それに比例するように性能も劣化する場合が多いです。

極端な話ですが、個別の列にする必要があるのは、検索条件、order by、group byで指定する列だけです。それ以外の列は、DB上は1個の列に値を格納し、アプリケーション側でその内容を分割して参照・更新するといった方法もあります。メインフレームでは、実際にこういった手法を取ることで、階層DBに近い性能を出すといった工夫をしているシステムもあります。

データ型に関してですが、text型の使用は、必要最小限にしてください。予め、データの最大長が予測できる場合は、varcharを使用してください。text型は、長さを指定することで、インデクスの定義も可能になっていますが、varcharに比べ有効利用してくれません。


http://q.hatena.ne.jp/ダミーです

◎質問者からの返答

丁寧に回答していただき、ありがとうございます。

>カテゴリ毎にA?Eと、表を分ける理由は何でしょうか?

例えば「スポーツ」と「エンターティメント」と「ファッション」というようにメインカテゴリがある場合、それぞれに必要な内容も異なりますよね?


「スポーツ」で必要な”基本情報”と「ファッション」で必要な”基本情報”のフィールド構成が同じだとは限りません。

ですので、分ける必要が出てきました。


この辺は文字数の関係で具体的に説明できませんでしたが、要はメインカテゴリとサブカテゴリの内容がすべて同じではないので、テーブル数が増える。増えることによって問題になるケースは何か?といった質問ですね。


私としては、出来る限りテーブル数を抑えたいのですが、後々のことを考えると、可能な限り分けた方が効率が良くなるような気がしています。


3 ● Yota
●26ポイント

「基本テーブル」というのを親テーブルと呼ぶとすれば、その子テーブル「アクセス情報」「コメント」などには同じID番号などを設定することで、関連性を示すことになると思います。

テーブル設計としては、子テーブルのIDは外部キー制約をつけて、親テーブルの主キーであるIDを参照します。(テーブルはTYPE=InnoDBのみ)

http://dev.mysql.com/doc/refman/4.1/ja/example-foreign-keys.html

テーブルを作るときに制約に伴って各テーブルのidにはINDEXが作られるためJOINによる結合を高速化できます。

このような理由で、とりあえずは問題ないと思いますが、データが大きくなったときにチューニングが必要になったら、my.cnf(my.ini)で下の項目を調整してみてください。

query_cache_size

table_cache

max_join_size

key_buffer_size

参照

http://www.mysql.gr.jp/Manual/mysql-4.00.12/manual.ja_MySQL_Data...

◎質問者からの返答

ありがとうございます。チューニングの件など、大変参考になりました。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ