MySQLで2つのテーブルを1つのテーブルにまとめたいと考えてます。


テーブル内容は、記事のタイトル名、投稿日時などの一覧テーブルA、もう一つは、その一覧テーブルと紐付けされた投稿記事本文を格納するテーブルBで下記のようになります。

テーブルA: タイトル名,投稿者名,投稿日時,テーブルBの本文ID
テーブルB: 本文ID,記事本文

テーブルAは投稿内容を一覧表示する際に単体でも使われます。
上記2つのテーブルを下記のように一つにまとめ、

テーブルC: タイトル名,投稿者名,投稿日時,記事本文

このテーブルCで投稿内容の一覧を表示したい場合、タイトル名,投稿者名,投稿日時にインデックスをはっておけば、テーブルA単体時と同等の速度がでるものなんでしょうか(もちろん、テーブルAも同じカラムにインデックスをはっているものとします)。

ちなみに数万件単位の投稿でInnoDBを使用した想定をしており、テーブルをまとめることのメリットとデメリットを教えて下さい。よろしくお願いします。

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

回答6件)

id:windofjuly No.1

回答回数2625ベストアンサー獲得回数1149

ポイント20pt

1つにまとめると、2つのテーブルを扱うよりも手順は楽になりますが、

記事が増えるにしたがって劇的に遅くなる可能性があります

 

レコード長が劇的に長くなっているため、

メモリ上のバッファに格納できるレコード数が大幅に減少し、

ハードディスクへのアクセスが増え、遅くなるという流れです

 

しかしながら、たかだか数万件規模なので、

パソコンをそのシステム専用に使う場合は無視できるかもしれません

共有サーバなどになれば利用できる物理メモリなどが限られてくるので、

問題が顕著にあらわれてくることもあるでしょう

 

結合はいつでもできますが分離は面倒です

私は分けたままにしておくことを勧めたいですね

id:xxmasaxx

仰るとおり、メンテが面倒なので一つにまとめたいというのもあります。

テーブルのサイズが巨大になってもインデックスのサイズがメモリ内に収まってれば大丈夫かな、と思ったんですがそう簡単にはいかないのでしょうか。

回答有り難うございます。

2010/11/18 10:36:27
id:b-wind No.2

回答回数3344ベストアンサー獲得回数440

ポイント20pt

まず確認。テーブルAの1レコードとテーブルBの1レコードは1対1対応?


1対1であればまとめた方がよい。

管理性もあるが、JOIN のコストが馬鹿にならないのでテーブルBの情報を参照するときに明らかに遅い。

このテーブルCで投稿内容の一覧を表示したい場合、タイトル名,投稿者名,投稿日時にインデックスをはっておけば、テーブルA単体時と同等の速度がでるものなんでしょうか

SELECT 文で元々テーブルAに存在したカラム名のみ指定しておけば速度的なデメリットは殆ど無い。

数万件程度ならなおさら。


ただ、このあたりは実際に入っているデータやアプリケーションからの参照と更新の度合いによっても変わってくる部分ではあるので、

きちんとベンチマークを取った方がよいとは思う。

DBMSのチューニングに王道は無いので。

id:xxmasaxx

テーブルのレコードは1対1です。

基本的には問題ないものの、用途次第ということですね。

回答どうも有り難うございました。

2010/11/18 11:37:33
id:Galapagos No.3

回答回数963ベストアンサー獲得回数89

ポイント20pt

テーブルAとテーブルBが1対1対応なら、テーブルCとして1本化すべきです。


インデックスを張る必要がなくなる分、SQL文が簡単になりますし(よって検索速度向上も期待できる)、メンテナンス性も良くなります。

id:xxmasaxx

なるほど。

有り難うございます。参考にさせて頂きます。

2010/11/18 12:42:07
id:tama213 No.4

回答回数486ベストアンサー獲得回数30

ポイント20pt

>テーブルA単体時と同等の速度がでるものなんでしょうか

データ件数が数万件程度で、

記事本文の大きさが常識の範囲内の大きさなら、同等の速度がでます。

>テーブルをまとめることのメリットとデメリットを教えて下さい。

参照とINSERTのみなら、2つに分ける意味を見出すほうが難しいかも。

更新とかそういうのが絡んでくるなら、何らかの条件で2つに分けるメリットがあるかも。

実践的データモデリング入門 (DB magazine selection)
真野 正
4798103853


通常は、正規化してテーブルを分けます。

この時点で、速度とかシステム用件に問題がなければそのままにします。

ここで問題がある場合は、一部を非正規化することを考えます。

数万件程度なら、JOINしてもそんなに遅くなりようがないとおもうけど。

>テーブルのサイズが巨大になってもインデックスのサイズがメモリ内に収まってれば大丈夫かな、

>と思ったんですがそう簡単にはいかないのでしょうか

記事本文の大きさが数KB程度なら、ぜんぜん問題にならないと思われます

id:xxmasaxx

まだプロトタイプで段階なので、最初は正規化してテーブルを分けるのもありですね。

参考になります。回答有り難うございます。

2010/11/18 21:06:18
id:yugmix No.5

回答回数27ベストアンサー獲得回数3

ポイント20pt

テーブル A の 本文 ID と テーブル B の本文 ID が 1:1 とのことなので、理論的には テーブルを2つに分ける必要はありません。 テーブル C のような構成で大丈夫です。

が、 記事本文 が非固定長でかつ長い場合等は、 そもそも 記事本文を RDBMS 上に持たずに、通常のファイルシステム上に置き、 本文 ID の代わりに、 ファイルシステムへのパス情報(もしくはファイルシステムへ到達できるID情報)を持たせることも検討された方が良いと思います。

特定の記事が集中して読まれるのか、全ての記事がまんべんなく読まれるのかで挙動が変わりますが、後者の場合 RDBMS 上のバッファのヒット率が落ちてしまうことが懸念されます。

id:xxmasaxx

記事本文はDBに格納しない、というのも一つの方法ですね。

レプリケーションする場合はrsyncでやればいいのかな。

回答どうも有り難うございます。

2010/11/18 21:14:33

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 windofiuly 62 37 2 2010-11-25 07:21:30
  • id:b-wind
    >まだプロトタイプで段階なので、最初は正規化してテーブルを分けるのもありですね。
    いや、レコードが1対1ならそれは正規化じゃないから。
    少なくとも通常行われる第3正規化までには入ってない。

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

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

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

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