2011-10-17 15 views
5

私はオンラインmuiltiplayerボードゲーム&にSQLサーバの質問があります。1対nの関係を適用する方法

ゲームで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. 

私は二つのことのように必要な、私は感じる:

  1. GameIdに基づいてtbPlayersInGameをロックする方法を。これは、プレーヤーをゲームに追加する際に使用されます。私が読んだところでは、GameId上のキーレンジロックのように聞こえるのは適切でしょう。
  2. 3対1のプレイヤーを追加しようとする試みが失敗するように1対2の関係を強制する方法。

答えて

1

カップル提案:

1)最初にテーブルに挿入、その後、ゲームがいっぱいでないことを確認するためにSELECTを行うtbPlayersInGameテーブルへの書き込みしようとします。このSELECTとINSERT INTOを、トランザクション分離レベルをシリアライズ可能に設定したトランザクションでラップします。あなたは列に持っているあなたのテーブルを設定することができ、Player1Id、Player2Id

+0

私はこのアプローチをとった。 「SETトランザクション分離レベルSERIALIZABLE INSERT INTO PlayersInGameをBEGIN (<ゲームGameId = @GameId FROM MaxPlayersを選択PlayersInGame GameId = @GameId FROM SELECT COUNT(*))TRANSACTION IFをBEGIN:クエリのようなものでした。 ... はTRAN RETURN 0 END ROLLBACK TRAN RETURN -1' 返信用 – Buurin

1

の代わりに1対nの関係 - :

2)の代わりにtbGameでの2つのフィールドを持って、別のtbPlayersInGameテーブルを持っていませんおそらくhost_playervisitor_playerというラベルが付いているか、必要な同等のもの(チェスのように - blackwhite)とラベル付けされています。これは、面白いことを最小限に抑え、関係の自然な状態を示すという利点があります。当然の

この選手の恒久的に限られた数があるようになっている場合にのみ動作します - ボードゲームのほとんどの場合のために、これはおそらく正常に動作します....

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

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回参加できないようにするため)、コンセプトはまだ有効です。

+0

感謝をCOMMIT。私はより明確にすべきだった、ゲームは2から8までのプレーヤーの様々な数を持つことができます。 Gameテーブルにプレーヤーを追加することは避けていました。 SQL Serverの挿入ステートメントにwhere句を追加できないと思います。私が間違っている場合は修正してください。 – Buurin

+0

Ack、そうです、あなたは 'WHERE'節を追加するだけではいけません - 私は' SELECT'の編集の一部としてそれを入れることを意図していました。 –