1

私はデータベース設計に不慣れで、格闘ゲーム用のPostgreSQLデータベースの設計に多くの問題を抱えています。

このゲームでは、プレイヤーは彼らの間で戦い、より良い武器や鎧を購入するためのリソースを獲得します。戦闘は将来のレビューのために記録され、戦闘の数は急速に増加すると予想されます。たとえば、1,000ラウンドで戦う1,000人のプレーヤーは500kの記録を生成します。

ゲームの双方向性は、戦闘機の装備と能力をアップグレードするためにポイントを使うように減らされます。戦闘はマシンによって解決されます。

詳細:

  • 特定の種類の武器または鎧は、各戦闘機が1回だけ所有できます。
  • 戦闘機はほぼ独占的にによって検索されidます。
  • 特定の戦闘機が所有している装備(武器や鎧)を検索する必要があることがよくありますが、特定の種類の武器を所有している戦闘機を検索することは期待していません。
  • winner戦闘はしばしばまたはによって検索されloserます。
  • 与えられた2つfightersは、異なる日付に複数回戦う可能性があるため、タプルはテーブル上で一意ではありませwinnerlosercombats
  • fightersテーブルには、同時に取得されることが多い多くの列が含まれています(戦闘が始まるたびに、関連するすべての情報を含むクラス「Fighter」の2つのオブジェクトを作成します)

これは私の現在のデザインです:

CREATE TABLE IF NOT EXISTS weapons (
    id serial PRIMARY KEY,
    *** Game stuff ***
);

CREATE TABLE IF NOT EXISTS armors (
    id serial PRIMARY KEY,
    *** Game stuff ***
);

CREATE TABLE IF NOT EXISTS fighters (
    id serial PRIMARY KEY,
    preferred_weapon INT references weapons(id),
    preferred_armor INT references armors(id),
    *** Game stuff ***
);

CREATE TABLE IF NOT EXISTS combats (
    id serial PRIMARY KEY,
    winner INT references fighters(id),
    loser  INT references fighters(id),
    *** Game stuff ***
);

CREATE TABLE IF NOT EXISTS fighters_weapons (
    fighter INT NOT NULL references fighters(id),
    weapon INT NOT NULL references weapons(id),
    PRIMARY KEY(fighter, weapon)
);

CREATE TABLE IF NOT EXISTS fighters_armors (
    fighter INT NOT NULL references fighters(id),
    armor INT NOT NULL references armors(id),
    PRIMARY KEY(fighter, armor)
);

私の質問は次のとおりです。

  1. 私のデザインはとても適していると思いますか?
  2. idすべてのテーブルの主キーとして列を含むデータベースの例をたくさん見てきました。その理由はありますか?私が使用している複数列の主キーの代わりにそれを行う必要がfighters_weaponsありfighters_armorsますか?
  3. PostgreSQLは主キーごとにインデックスを自動的に作成しますが、それで検索することを期待していないテーブルがいくつかあります(つまりcombats)。パフォーマンスのためにインデックスを削除する必要がありますか?PostgreSQLは既存の制約について文句を言います。
  4. fighters_weaponsとを検索fighters_armorsするfighterので、これらのテーブルにこのすべての列のインデックスを作成する必要があると思いますか?combatswinnerloser
  5. パフォーマンス改善のアドバイスはありますか?最もよく使用される操作は、戦闘機の挿入と照会、特定の戦闘機の装備の照会、および戦闘の挿入です。

どうもありがとう :)

4

1 に答える 1

0

明確な質問に対処するには:

2)主キーとして「自然な」値を使用することが望ましい場合があります。つまり、シリアルIDが存在する場合は、シリアルIDではありません。シリアルIDを識別子として使用する可能性が低い場合は、追加しない方が少し良いと思います。

3)戦闘テーブルに非常に迅速に多くの行を挿入するつもりでない限り、id列にインデックスを付けることはおそらくそれほど害にはなりません。

4)インデックス{fighter、weapon}が存在する場合、{fighter}にインデックスを作成する必要はありません。同様に、インデックス{fighter、armor}が存在する場合、{fighter}にインデックスを作成する必要はありません。一般に、別の複数列のインデックスのプレフィックスであるインデックスを作成してもメリットはありません。これとは別に、戦闘で{winner}インデックスと{loser}インデックスを作成することは、あなたが説明したアクセスパターンを考えると良い考えのように思えます。

5)テーブルの設計以外にも、データベースを自分でインストールした場合に設定できるデータベース調整パラメーターがいくつかあります。経験豊富なデータベース管理者がデータベースを設定している場合、おそらくすでにこれを行っています。

于 2013-02-21T00:20:34.867 に答える