5

私はオンラインのマルチプレイヤーボードゲームに取り組んでおり、SQLサーバーに関する質問があります。

ゲームで2人のプレーヤーが許可されていると仮定しましょう。ゲームが作成されると、作成者が最初のユーザーとして追加されます。

その時点で、2人のユーザーが同時にゲームに参加しようとする可能性があります。これらのユーザーの1人をブロックする必要があります。

私のデータベーススキーマは次のとおりです。

tbGame - contains a list of all games. PrimaryKey is GameId
tbPlayers - contains a list of all registered users. PrimaryKey is PlayerId
tbPlayersInGame - contains a list of all players in each game. Foreign key 
                  relations to tbGame and tbPlayers.

私は2つのものが必要だと感じています:

  1. GameIdに基づいてtbPlayersInGameをロックする方法。これは、ゲームにプレーヤーを追加するときに使用されます。私が読んだことから、(GameIdの)キー範囲ロックが適切であるように聞こえます。
  2. 3人目のプレーヤーを追加しようとして失敗するように1対2の関係を強制する方法。
4

2 に答える 2

1

いくつかの提案:

1)tbPlayersInGameテーブルに書き込もうとするときは、最初にSELECTを実行してゲームがいっぱいでないことを確認してから、テーブルにINSERTを実行します。このSELECTとINSERTINTOを、トランザクション分離レベルがシリアライズ可能に設定されたトランザクションでラップします。

2)個別のtbPlayersInGameテーブルを用意せず、代わりにtbGameにPlayer1Id、Player2Idの2つのフィールドを用意します。

于 2011-10-17T23:41:13.173 に答える
1

host_player1 対 n の関係の代わりに、おそらくandというラベルの付いた列を持つvisitor_playerようにテーブルblackを設定することができますwhite。これには、面白いことを最小限に抑え、関係の自然な状態を示すという利点があります.

もちろん、これは永久に限られた数のプレーヤーがいると思われる場合にのみ機能します-ボードゲームのほとんどのインスタンスでは、これはおそらくうまく機能します....

上限が (何らかの理由で) 変更可能なゲームを作成しようとしている場合は、次のステートメントで使用可能な空きスロットを「検出」できます。

INSERT INTO game_players (game_id, player_id) 
SELECT VALUES (:GAME_ID, :PLAYER_ID)
WHERE :MAX_PLAYER_COUNT > (SELECT COUNT(*)
                           FROM game_players
                           WHERE game_id = :GAME_ID)

エラー コード 100 (「行が選択されていない/更新されていません」) が返された場合は、プレーヤー リストがいっぱいです。(プレイヤーが 2 回参加するのを防ぐために) 他の条件を追加する必要があるかもしれませんが、この概念は引き続き機能するはずです。

于 2011-10-17T23:48:38.610 に答える