ここから本文です

1億のレコードか1万のテーブル。よい設計はどっち?

ms5********さん

2009/8/2521:41:57

1億のレコードか1万のテーブル。よい設計はどっち?

データベース初心者です。
VC++ 2008 で、競馬 DB を作成するプログラムを書いています。
困っているのは、過去5年のすべてのオッズを格納するテーブルの
設計についてです。

過去5年でだいたい2万ほどのレースがあり、
各レースに 5000 ほどのオッズがあります。
ごく簡略化しますが、はじめはこのようなテーブルを組みました。

レース番号,馬1,馬2,馬3,オッズ
1,1,2,3,70.2
1,1,2,4,45.4
1,1,2,5,91.9

2,1,2,3,1371.4
2,1,2,4,710.6


このまま格納し切ったとすると、
レコードが1億を超す計算になります。
Webからデータを受け取りながら
DB を構築していくプログラムなんですが、
動かしてみると終了まで何週間もかかるペースだとわかり、
今はこの設計を疑っています。

別のレースのオッズを同時に取り出す必要はないので
テーブルを分けることも考えたんですが、
それだとレース番号とテーブルを関連付ける方法がわからず、
どうすべきなのか悩んでいます。

1億レコードのテーブルは
構築に時間がかかったとしても運用開始後は問題ないのか、
それともテーブルを分割すべきなのか、
あるいは第3の方法があるのか。

DB の設計に造詣が深い方、
なにとぞご指南のほどお願いいたします。

閲覧数:
7,939
回答数:
1
お礼:
500枚

違反報告

ベストアンサーに選ばれた回答

emp********さん

2009/8/2900:45:19

根本的なところで、テーブルを分割するしないに関わらず、総レコード数は1億になるんですよね。1レコード10Byteとしても、1GByteのデータを扱うことになります。操作履歴等の通常参照しないデータであればまだしも、普段の検索対象となるデータだとすると、参照時には大きなインデックスを使うか、多段での検索を行うかになり、検索コストが高いため厳しいでしょう。

解決するには、いかにして検索コストを下げるかです。
1つのアプローチとしては、レコード件数を減らすことです。1レース分のオッズ表を外部テキストなりCLOBなりに詰め込んで1レコードにしてしまえば、過去レースのオッズ表の出力だけが要件であれば、機能的に十分ながらレコード数を1/5000にできますので、検索性能は改善します。
他のアプローチとしては、不要なデータを投入しないことです。例えば過去の万馬券的中率を知りたいだけなのであれば、100未満のオッズは破棄できます。オッズカラムを廃止してbooleanの万馬券カラムにデータを入れるようにすれば、データサイズが縮小できますので、同じく検索性能は改善します。
要は、汎用的なデータを持つのではなく、利用方法を満たすための必要最低限の粒度・情報量にするということです。まぁ予算が潤沢であれば、エンタープライズ系システムのアプローチとなる、パーティショニング等でゴリ押しもできますが・・・。

なお、いずれの場合も投入時の性能の改善にはなりませんが、「インデックスを使う=参照速度UP&更新速度DOWN」なので、アンケート等のデータ専門でない限りは諦める必要があります。逆に収集専門ということでしたら、インデックスは張らず(PKも設定しない)、黙々とデータを書き込ませるのが一番速いです。

質問した人からのコメント

2009/9/1 22:15:10

明快な回答ありがとうございます。
テーブルを分割してもあまり意味はないということがわかりました。
また、インデックスという概念も知らなかった初心者ですので、
質問の内容のみならずいろいろご提案いただき非常に参考になりました。
ありがとうございました。

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる