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

データベースの設計について。

データベースを効率よく処理させるために、設計を考えています。
内容はユーザーごとに作ったゲームの得点管理です。

・ユーザーテーブル(user_t)
・ゲームテーブル(game_t)
・得点結果テーブル(point_t)
で作れると思います。
しかし、これでつくると、得点結果テーブルに大量の得点結果がたまり、ゲームごとの集計するのが処理が重くなるのかなと考えています。

これを解決するために、得点結果テーブルをゲームごとに生成されるようにしてはどうだろうと考えました。

ゲームごとの場合、(g1_point_t,g2_point_t…)というのが大量に作られますが、ゲームテーブルと、得点結果テーブルをジョイントする必要がない分、処理は速くなりそうです。

しかし、テーブルが大量に出てても、いいものなのかわからないのです。
テーブル数に制限とかあるのか、または、テーブルはあま多くならないように設計すべきなのか教えてください。

DBはMysqlを検討しています。




●質問者: dingding
●カテゴリ:インターネット ウェブ制作
✍キーワード:DB MySQL いもの ゲーム データベース
○ 状態 :終了
└ 回答数 : 4/4件

▽最新の回答へ

1 ● samasuya
●20ポイント

その設計だと、ユーザーのゲームごとの得点一覧を表示するときに、かなりメンドクサイことになりますが、いいんでしょうか?

得点テーブルにINDEXをつければ、ある程度は処理の重さは

緩和できると思います。

あとMySQL的には逆に処理が重くなるんじゃないでしょうか?

http://dev.mysql.com/doc/refman/4.1/ja/creating-many-tables.html

◎質問者からの返答

説明不足でした。

ユーザーテーブルに入っているユーザーは、ゲームを作るユーザで、得点結果が登録されるのは、ゲームをする一般ユーザーの得点です。

一般ユーザはDBに登録せず、「どのゲームで何点とった」という結果をひたすら登録され、「Aゲームは○人やっていて、平均が×点である」という結果を取得することになります。

そうなると、AゲームとBゲームの得点に関係性はないので、ゲームごとに得点のテーブルを分けてもいいかなと考えています。


2 ● ootatmt
●20ポイント

データとしては、ユーザ、ゲーム、得点だけですか?

それなら次の3つのテーブルでどうですか。


table1: ID, 日時, ゲームID, ユーザID, 得点

table2: ゲームID, ゲーム属性 etc.

table3: ユーザID, ユーザ属性 etc.


通常は table1 にデータを溜めていき、

新しいゲームやユーザが追加になったときだけ table2, table3 を変更することになります。


3 ● きゃづみぃ
●30ポイント

レコード件数は、DBの性能によって これぐらいかなという線引きがあります。

マイクロソフトのアクセスなど 簡易のDB用でも 1万件ぐらいは いけると言われてますので、1万件以下ぐらいでしたら、特に 気にする必要はないと思いますよ。

業務用などだと 数千万件入っているテーブルがあったりする場合があります。

テーブルを 一つにすれば 検索速度は 速くなりますが、その分 ディスク容量をくいます。

テーブルAとテーブルBの関係が 1対1ならば、テーブルAにテーブルBを入れてしまったほうがいいです。

テーブルAとテーブルBの関係が 1対多ならば、テーブルAとテーブルBを分けたほうがいいですね。

テーブル数の制限というのも ディスク容量によりますね。

あと 得点結果テーブルが ゲーム毎で作られるというのは ちょっと わからないですね。

普通は、得点結果テーブルの中にどのゲームなのかを示す番号を もたせ、得点結果テーブルは 一つだけにしたほうがいいでしょう。

どんどん テーブルが 増えるシステムは 考え物です。

初期設定で 決めたテーブルだけで あとは 増やさないのが 一般的でしょう。

もちろん 意図的に テーブルを増やす場合もありますが、基本的には テーブルは 増やさない方向で 設計したほうがいいですよ。

◎質問者からの返答

レコード件数の上限は、MySQLの場合、どのくらい見ておくのが適切なのでしょうか?

テーブルを増やす設計は私も今まで極力避けているのですが、今回の内容の場合、分けたほうが処理の効率がいいのかなと考えて、わからなくなり質問させて頂きました。


4 ● ANSUKOEMU
●50ポイント

>一般ユーザはDBに登録せず、「どのゲームで何点とった」という結果をひたすら登録され、

>「Aゲームは○人やっていて、平均が×点である」という結果を取得することになります。

一般ユーザを登録せず点数のみ記録するということは、ゲーム利用者の人数は延べ人数と

いうことでしょうか?

データを履歴的に抱えるように見えますが、平均点などの参照があるたびにそのテーブルから

計算しなおすのは効率が悪いです。


1案として、game_tのレイアウトを以下のようにしておくのはどうでしょう。

・ゲームID (PK)

・ゲーム作成UserID

・ゲーム属性情報

・得点合計(全プレイのトータル)

・現利用回数(延べ人数)

・必要なら、最高得点も用意。

1ゲームについて1レコードです。

得点テーブルに得点が記録されるときに、このレコードも更新しておけば、

通常の平均点参照などはこちらのテーブルで済みます。

更新は、

得点合計=得点合計+追加得点

延べ人数=延べ人数+1

です。

平均点は 得点合計/延べ人数 で計算できます。

得点合計の桁が大きくなりすぎる可能性がありますので、持ち方は工夫が必要です。


ゲーム得点といえばハイスコアリストがつき物ですが、別テーブルでの管理となるでしょう。

環境次第ですが、ベスト100程度までの保持なら、以下のような感じで十分いけると思います。

・なんらかのユニークキー(DBMSによっては不要かも)

・ゲーム作成UserID

・ゲームID

・順位 (1?例えば100)

・得点

・プレイヤー名

・記録日時

新しい得点を追加する場合、1トランザクションで以下の処理をしてあげます。

新しい得点以上の得点を保持するレコードの件数を取得(1足した値が新しい得点の順位)

新しい得点が保持件数内であれば、

新しい得点の順位以上の順位を保持するレコードについて、順位=順位+1のUpdate。

新しい得点のレコードをInsert。

必要があれば、順位が保存対象から外れたレコードをDelete。


この方法だと、同じ得点なら元からあったデータが順位が前になります。

一見更新件数が多くなるように感じますが、1度に更新しますし、上位スコアばかりが毎回出る

わけではないので問題ないでしょう。

レコードに順位も持たせているので、上位から20件区切りでページを分けて表示するとか、

上位10位内の平均点を表示するとかも楽になります。


あと、ゲームにより、得点が多い方が上位になるケースと、値が小さい方が上位になるケース

(タイムアタックなど)が在りますので、ゲームによって大小の見方や表示フォーマットを

変えられるようにした方がいいですね。

◎質問者からの返答

大変詳しい説明ありがとうございます。

先ほどまでのはてながつながりにくい時間に考えていた「いちいち全部のユーザーのプレイ回数分レコードを持つ必要がないかな」と思っていたので、まさにご提案頂いた方法がジャストです。

とってもとってもためになります。

ありがとうございました。

関連質問


●質問をもっと探す●



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