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系以降の考え方でお願いします。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:
  • 終了:2007/08/15 11:06:31
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:KUROX No.1

回答回数3542ベストアンサー獲得回数140

ポイント27pt

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

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

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

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

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

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

思っています。

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

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

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

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

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

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

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

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

バランスだと思います。

id:kt26

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

2007/08/10 17:36:45
id:chuken_kenkou No.2

回答回数722ベストアンサー獲得回数54

ポイント27pt

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/ダミーです

id:kt26

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

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

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


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

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


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


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

2007/08/10 17:27:18
id:Yota No.3

回答回数453ベストアンサー獲得回数28

ポイント26pt

「基本テーブル」というのを親テーブルと呼ぶとすれば、その子テーブル「アクセス情報」「コメント」などには同じ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...

id:kt26

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

2007/08/10 17:29:10

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません