データベース設計|ゲームプレイヤーアクティビティデータベース|最終コース設計

序文

那么这里博主先安利一些干货满满的专栏了!

首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。

高质量博客汇总https://blog.csdn.net/yu_cblog/category_12379430.html?spm=1001.2014.3001.5482


デザイン内容 

ゲーム会社向けに簡単なデータベースを設計してください。要件は、当社が運営する各種ゲームにログインできること、ゲームにログインしてゲームをプレイできること、またはゲームにチャージできることです。多くの場合、ゲームではいくつかのアクティビティが開始され、プレイヤーは特定のアクティビティに参加できます。

例証します:

  1. ゲームの種類には、無料のものと有料のものがあります。無料ではないゲームをプレイするには有料
  2. プレーヤーは参加できない、または最大 10 個のアクティビティに参加できません
  3. イベントには任意の数のプレイヤーが参加できます

概念設計(ER図)

トピックの要件:

完全な ER モデル図を描きます。

マッピングのベース (1 対 1、1 対多、多対多)、参加のタイプ (部分的および全体)、および主キーを指定します。結果を図1に示します。ここで、アンダースコアはテーブルの主キーを表します。

図1
図 1 データベース ER 図、およびマッピング カーディナリティと参加タイプの注釈

リレーショナルスキーマ

トピックの要件: ER 図をリレーショナル スキーマに変換し、主キーをマークします。

示されているように、関係スキーマは図 2 に示されています。

図2 データベースのリレーショナルスキーマ

 すべてのテーブルの主キーには下線が付けられています。

SQLコード

テーブル作成 SQL ステートメントおよびリレーショナル スキーマに関連する制約

ゲームエンティティテーブルを作成する

CREATE TABLE Games ( 
  GameID Counter PRIMARY KEY, 
  GameName varchar(255) NOT NULL, 
  Cost Money デフォルト 0, 
  GameType varchar(10) default 免费 NOT NULL 
);

関連する制約

GameID:ゲームID(カウンター)

GameName:ゲーム名 (最大長 255 の文字列)

コスト:ゲームコスト (デフォルトは 0 通貨タイプ)

GameType:ゲーム タイプ (デフォルトは「free」、非 null 制約の下で長さ 10 の文字列、制約は値が「有料」または「無料」のいずれか 1 つだけであることです)

GamesRuleゲームテーブルの名前付き制約を設定します。制約ゲームタイプは「無料」または「有料」のみです。

ALTER TABLE Games ADD CONSTRAINT GamesRule CHECK (GameType IN ('Free', 'Paid'));

アクティビティテーブルの作成

CREATE TABLE アクティビティ (
  アクティビティID カウンター主キー、
  アクティビティ名 varchar(255) NOT NULL 
);

関連する制約

ActivityID:アクティビティID (カウンタ)

ActivityName:アクティビティ名 (最大長 255 の文字列、非 null 制約の対象)

プレーヤーエンティティテーブルを作成する

CREATE TABLE Players ( 
  PlayerID Counter PRIMARY KEY、
  PlayerName varchar(255) NOT NULL、
  PlayerPass varchar(255) NOT NULL 
);

関連する制約

PlayerID: プレイヤーID(カウンター)

PlayerName: プレーヤー名 (最大長 255 の文字列、非 null 制約の対象)

PlayerPass: プレーヤーのパスワード (最大長 255 の文字列、非 null 制約の対象)

プレイヤーゲーム関係テーブル(ログインテーブル)を作成する

CREATE TABLE Login ( 
  PlayerID INT, 
  GameID INT, 
  ParticipateActivity BIT DEFAULT 0, 
  Balance MONEY NOT NULL DEFAULT 0, 
  LoginTime DATETIME DEFAULT GETDATE(), 
  FOREIGN KEY (PlayerID) REFERENCES Players(PlayerID), 
  FOREIGN KEY (GameID) REFERENCES Games(GameID) 
);

関連する制約

PlayerID:プレイヤーID (整数)

GameID:ゲームID(整数)

ParticipateActivity:アクティビティに参加するかどうか (デフォルトは 0 ビットのデータ型)

残高マネー:残高 (空でない制約の下では、デフォルトは 0 通貨タイプです)

LoginTime:最終ログイン時刻(DATETIME型)

外部キー制約: PlayerID 外部キーは Players(PlayerID) を参照し、GameID 外部キーはゲーム (GameID) を参照します。

ゲームアクティビティ関係テーブルを作成する

CREATE TABLE GameActivities ( 
  GameID int, 
  ActivityID int, 
  FOREIGN KEY (GameID) REFERENCES Games(GameID), 
  FOREIGN KEY (ActivityID) REFERENCES activity(ActivityID) 
);

関連する制約

GameID:ゲームID(整数)

ActivityID:アクティビティID (整数)

外部キー制約: GameID 外部キーはゲーム (GameID) を参照し、ActivityID 外部キーはアクティビティ (ActivityID) を参照します。

プレイヤーアクティビティ関係テーブルを作成する

CREATE TABLE PlayerActivities ( 
  PlayerID int, 
  ActivityID int, 
  FOREIGN KEY (PlayerID) REFERENCES Players(PlayerID), 
  FOREIGN KEY (ActivityID) REFERENCES activity(ActivityID) 
);

関連する制約

PlayerID:プレイヤーID (整数)

ActivityID:アクティビティID (整数)

外部キー制約: PlayerID 外部キーは Players(PlayerID) を参照し、ActivityID 外部キーはアクティビティ (ActivityID) を参照します。

トリガーを作成する

プレイヤーが参加したイベントの数が制限の 10 に達したかどうかを確認するトリガーを作成します。


各行の
ログイン時に挿入する前にトリガー LimitPlayerActivities を作成します。 
BEGIN 
    DECLARE total_activities INT; 
    -- 計算
    SELECT COUNT(*) INTO total_activities 
    FROM Login 
    WHERE PlayerID = NEW.PlayerID; 
    IF total_activities >= 10 THEN 
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'プレイヤーは最大 10 個のアクティビティに参加できます。'; 
    終了 IF; 
終わり;
    

お問い合わせ

ゲーム A によって開始されたすべてのアクティビティに参加したすべてのプレイヤーの SQL ステートメントを検索します。

SELECT DISTINCT Players.PlayerID、Players.PlayerName 
FROM Players 
INNER JOIN Login ON Players.PlayerID = Login.PlayerID 
INNER JOIN GameActivities ON Login.GameID = GameActivities.GameID 
INNER JOIN アクティビティ ON GameActivities.ActivityID = activity.ActivityID 
INNER JOIN ゲーム ON GameActivities。ゲームID = Games.GameID 
WHERE Games.GameName = 'A';

アクティビティを 3 回以上起動したゲームの SQL ステートメントを確認します。

SELECT G.GameID, G.GameName, COUNT(GA.ActivityID) AS ActivityCount 
FROM Games G 
JOIN GameActivities GA ON G.GameID = GA.GameID 
GROUP BY G.GameID, G.GameName 
HAVING COUNT(GA.ActivityID) > 3;

ゲーム A を特定のプレイヤーよりも高くリチャージするすべてのプレイヤー ID を見つけるための関係代数

 この関係代数の公式は一連の演算を記述しており、各ステップの意味と目的は次のとおりです。

  1. Login ⨝ Playersこの手順では、接続操作を表す ⨝ 演算子を使用して、「ログイン」と「プレイヤー」の関係を接続します。結合操作は、2 つのリレーション間の共通プロパティに基づいて、結合条件を満たすタプルを結合します。このステップの目的は、後続の操作のために「ログイン」と「プレイヤー」の間の関係のデータを接続することです。

  2. ρ PlayerID/PlayerID (Login ⨝ Players)このステップでは、関係の名前を変更する ρ 演算子を使用します。この式では、「Login ⨝ Players」の結果の名前を「PlayerID」に変更します。つまり、結果の PlayerID フィールドの名前を PlayerID に変更します。このステップの目的は、次のステップをより適切に表現することです。

  3. σ GameName='A' ⨝ Balance > Amountこのステップでは σ 演算子を使用します。その機能は、関係に対して選択操作を実行すること、つまり、指定された条件に従って修飾されたタプルをフィルターで除外することです。この式では、GameName が「A」で、残高が Amount より大きいタプルを選択します。このステップの目的は、特定の条件に従って要件を満たすデータをフィルタリングすることです。

  4. π PlayerIDこのステップでは π 演算子を使用し、その機能は関係に対して射影演算を実行することです。つまり、指定された属性列のみが保持されます。この式では、PlayerID 属性列のみを保持し、他の属性列は除外します。このステップの目的は、前のステップでフィルタリングされた結果から PlayerID 属性のみを保持し、最終結果を取得することです。

要約すると、関係代数式の意味は次のとおりです。「ログイン」と「プレイヤー」の関係から一致するすべてのタプルを接続 (⨝) し、次に従ってゲーム名が 'A' で、残高が金額より大きいことを選択 (σ) します。条件を指定し、最後に (π)PlayerID 属性列のみを保持します。この操作の目的は、リチャージが特定のプレーヤーよりも高いすべてのプレーヤー ID を見つけることです。

いくつかの実用的な SQL プロシージャと関数を設計する

特定のゲームにログイン(有料ゲームをプレイ)した人数をカウントする(機能)

CREATE PROCEDURE GetLoginCountByGameName(IN gameName VARCHAR(255), OUT loginCount INT) 
BEGIN 
    SELECT COUNT(DISTINCT PlayerID) INTO loginCount 
    FROM Login 
    INNER JOIN Games ON Login.GameID = Games.GameID 
    WHERE Games.GameName = gameName; 
終わり; 
-- 调用
CALL GetLoginCountByGameName('A', @loginCount); 
@ログイン数を選択します。

特定のゲームに対してその日にすべてのプレイヤーが支払った合計金額をカウントします (プロセス)

まずストアド プロシージャを作成する必要があります。ストアド プロシージャの入力パラメータはゲーム名を表す 1、出力結果は合計金額を表す 1 で、合計金額の計算には SUM 集計関数が使用されますプレイヤー ゲーム テーブルとゲーム テーブルを結合する必要があります。内部接続を実行します。内部接続条件はゲーム ID が等しいことです。また、すべてのプレイヤー レコードとそれに対応するゲーム コストを取得できるように句を追加しますwhere。入力パラメータで指定されたゲームをプレイしたとき、コストの合計が最終的な合計結果が得られるので、その合計結果を出力することを選択できます。最後に、ストアド プロシージャの呼び出しをテストしたところCalculateTotalPaymentsByGameName、正しい値が取得されたことがわかりました。SQLコードは以下の通りです。

CREATE PROCEDURE CalculateTotalPaymentsByGameName(IN gameName VARCHAR(255), OUT totalPayments DECIMAL(10, 2)) 
BEGIN 
    SELECT SUM(Games.Cost) INTO totalPayments 
    FROM Games 
    INNER JOIN Login ON Login.GameID = Games.GameID 
    WHERE Games.GameName = gameName; 
終わり; 
CALL CalculateTotalPaymentsByGameName('A', @totalPayments); 
@totalPaymentsを選択します。

実用的なSQLトリガーを設計する

プレイヤーを削除すると、プレイヤーの関連情報(すべてのゲームとアクティビティ)も一緒に削除されます。

DELIMITER // 
CREATE TRIGGER trg_DeletePlayer 
BEFORE DELETE ON Players 
FOR EACH ROW 
BEGIN 
  -- プレーヤーに関連するログイン レコードを削除します
  DELETE FROM Login WHERE PlayerID = OLD.PlayerID; 
  -- プレーヤーに関連する PlayerActivities レコードを削除します
  DELETE FROM PlayerActivities WHERE PlayerID = OLD.PlayerID; 
END // 
DELIMITER ;

おすすめ

転載: blog.csdn.net/Yu_Cblog/article/details/132157187