optimized schema
This commit is contained in:
parent
80a8f6775c
commit
d174f74408
3 changed files with 125 additions and 60 deletions
|
|
@ -3,7 +3,8 @@
|
|||
```mermaid
|
||||
erDiagram
|
||||
user {
|
||||
string name PK
|
||||
serial id PK
|
||||
string name
|
||||
}
|
||||
|
||||
game {
|
||||
|
|
@ -11,17 +12,33 @@ erDiagram
|
|||
int score
|
||||
time playtime
|
||||
date date
|
||||
string username FK
|
||||
int user_id FK
|
||||
}
|
||||
|
||||
user ||--O{ game : "played"
|
||||
|
||||
user_data {
|
||||
string username PK
|
||||
user_scores {
|
||||
int user_id PK
|
||||
int highscore
|
||||
int total_score
|
||||
int total_playtime
|
||||
int average_score
|
||||
int games_played
|
||||
}
|
||||
```
|
||||
|
||||
lb_highscore {
|
||||
int rank
|
||||
int user_id
|
||||
int highscore
|
||||
}
|
||||
|
||||
lb_total_playtime {
|
||||
int rank
|
||||
int user_id
|
||||
time total_playtime
|
||||
}
|
||||
|
||||
user ||--O{ game : "played"
|
||||
user ||--|| user_scores : ""
|
||||
```
|
||||
`lb_highscore` and `lb_total_playtime` are views querying the `user_scores` table.
|
||||
|
||||
A trigger function on insert to the `user` table creates a new row in `user_scores`. Everytime a new `game` is inserted, the row is updated.
|
||||
|
|
@ -1,5 +1,16 @@
|
|||
CREATE TABLE "user" (
|
||||
username VARCHAR(32) PRIMARY KEY
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(32)
|
||||
);
|
||||
|
||||
CREATE TABLE user_scores (
|
||||
user_id INT PRIMARY KEY REFERENCES "user",
|
||||
highscore INT NOT NULL DEFAULT 0,
|
||||
total_score INT NOT NULL DEFAULT 0,
|
||||
total_playtime TIME NOT NULL DEFAULT '00:00:00',
|
||||
average_score INT NOT NULL DEFAULT 0,
|
||||
games_played INT NOT NULL DEFAULT 0,
|
||||
FOREIGN KEY (user_id) REFERENCES "user"
|
||||
);
|
||||
|
||||
CREATE TABLE game (
|
||||
|
|
@ -7,26 +18,64 @@ CREATE TABLE game (
|
|||
score INTEGER NOT NULL,
|
||||
playtime TIME NOT NULL,
|
||||
date DATE NOT NULL,
|
||||
username VARCHAR(32) NOT NULL,
|
||||
FOREIGN KEY (username) REFERENCES "user"
|
||||
user_id INT NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES "user"
|
||||
);
|
||||
|
||||
CREATE VIEW user_data AS (
|
||||
CREATE VIEW lb_highscore AS (
|
||||
SELECT row_number() OVER (ORDER BY highscore DESC) AS rank, user_id, highscore FROM user_scores ORDER BY rank
|
||||
);
|
||||
|
||||
CREATE VIEW lb_total_playtime AS (
|
||||
SELECT row_number() OVER (ORDER BY total_playtime DESC) AS rank, user_id, total_playtime AS total_playtime FROM user_scores ORDER BY rank
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION insert_new_user_scores()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql AS
|
||||
$$
|
||||
BEGIN
|
||||
INSERT INTO user_scores (user_id) VALUES (NEW.id);
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE TRIGGER user_added
|
||||
AFTER INSERT ON "user"
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION insert_new_user_scores();
|
||||
|
||||
CREATE OR REPLACE FUNCTION update_user_scores()
|
||||
RETURNS TRIGGER
|
||||
LANGUAGE plpgsql AS
|
||||
$$
|
||||
DECLARE
|
||||
row user_scores%ROWTYPE;
|
||||
BEGIN
|
||||
SELECT
|
||||
username,
|
||||
user_id,
|
||||
max(score) AS highscore,
|
||||
sum(score) AS total_score,
|
||||
sum(playtime) AS total_playtime,
|
||||
avg(score) AS average_score,
|
||||
count(*) AS games_played
|
||||
INTO row
|
||||
FROM game
|
||||
GROUP BY username
|
||||
);
|
||||
WHERE user_id = NEW.user_id
|
||||
GROUP BY user_id;
|
||||
|
||||
CREATE VIEW lb_highscore AS (
|
||||
SELECT row_number() OVER (ORDER BY max(score) DESC) AS rank, username, max(score) AS highscore FROM game GROUP BY username ORDER BY rank
|
||||
);
|
||||
UPDATE user_scores SET
|
||||
highscore = row.highscore,
|
||||
total_score = row.total_score,
|
||||
total_playtime = row.total_playtime,
|
||||
average_score = row.average_score,
|
||||
games_played = row.games_played
|
||||
WHERE user_id = row.user_id;
|
||||
RETURN NEW;
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE VIEW lb_total_playtime AS (
|
||||
SELECT row_number() OVER (ORDER BY sum(playtime) DESC) AS rank, username, sum(playtime) AS total_playtime FROM game GROUP BY username ORDER BY rank
|
||||
);
|
||||
CREATE TRIGGER game_played
|
||||
AFTER INSERT ON game
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_user_scores();
|
||||
|
|
|
|||
|
|
@ -1,41 +1,40 @@
|
|||
insert into "user" (username) values ('dpettus0');
|
||||
insert into "user" (username) values ('egreetland1');
|
||||
insert into "user" (username) values ('smontford2');
|
||||
insert into "user" (username) values ('idagwell3');
|
||||
insert into "user" (username) values ('lgagan4');
|
||||
insert into "user" (username) values ('acarmont5');
|
||||
insert into "user" (username) values ('kjermyn6');
|
||||
insert into "user" (username) values ('dokieran7');
|
||||
insert into "user" (username) values ('pdrinkel8');
|
||||
insert into "user" (username) values ('amelladew9');
|
||||
insert into "user" (name) values ('dpettus0');
|
||||
insert into "user" (name) values ('egreetland1');
|
||||
insert into "user" (name) values ('smontford2');
|
||||
insert into "user" (name) values ('idagwell3');
|
||||
insert into "user" (name) values ('lgagan4');
|
||||
insert into "user" (name) values ('acarmont5');
|
||||
insert into "user" (name) values ('kjermyn6');
|
||||
insert into "user" (name) values ('dokieran7');
|
||||
insert into "user" (name) values ('pdrinkel8');
|
||||
|
||||
insert into game (username, score, playtime, date) values ('dpettus0', 74, '19:59', '2022-07-19');
|
||||
insert into game (username, score, playtime, date) values ('dpettus0', 86, '20:32', '2022-11-24');
|
||||
insert into game (username, score, playtime, date) values ('dpettus0', 68, '10:41', '2022-03-24');
|
||||
insert into game (username, score, playtime, date) values ('egreetland1', 39, '5:55', '2022-06-01');
|
||||
insert into game (username, score, playtime, date) values ('egreetland1', 20, '9:23', '2022-03-12');
|
||||
insert into game (username, score, playtime, date) values ('egreetland1', 28, '23:45', '2022-04-01');
|
||||
insert into game (username, score, playtime, date) values ('smontford2', 44, '18:43', '2022-06-24');
|
||||
insert into game (username, score, playtime, date) values ('smontford2', 92, '14:54', '2022-11-06');
|
||||
insert into game (username, score, playtime, date) values ('smontford2', 73, '0:45', '2022-07-26');
|
||||
insert into game (username, score, playtime, date) values ('idagwell3', 27, '2:49', '2022-02-03');
|
||||
insert into game (username, score, playtime, date) values ('idagwell3', 26, '2:32', '2022-07-19');
|
||||
insert into game (username, score, playtime, date) values ('idagwell3', 12, '17:03', '2022-04-25');
|
||||
insert into game (username, score, playtime, date) values ('lgagan4', 6, '8:49', '2021-12-03');
|
||||
insert into game (username, score, playtime, date) values ('lgagan4', 22, '22:27', '2022-03-02');
|
||||
insert into game (username, score, playtime, date) values ('lgagan4', 94, '1:04', '2022-10-19');
|
||||
insert into game (username, score, playtime, date) values ('acarmont5', 2, '2:14', '2022-04-06');
|
||||
insert into game (username, score, playtime, date) values ('acarmont5', 21, '17:18', '2022-06-03');
|
||||
insert into game (username, score, playtime, date) values ('acarmont5', 33, '16:01', '2022-02-02');
|
||||
insert into game (username, score, playtime, date) values ('kjermyn6', 27, '7:03', '2022-02-06');
|
||||
insert into game (username, score, playtime, date) values ('kjermyn6', 62, '0:45', '2022-11-15');
|
||||
insert into game (username, score, playtime, date) values ('kjermyn6', 12, '8:54', '2022-06-29');
|
||||
insert into game (username, score, playtime, date) values ('dokieran7', 63, '16:01', '2022-11-05');
|
||||
insert into game (username, score, playtime, date) values ('dokieran7', 29, '0:46', '2022-10-01');
|
||||
insert into game (username, score, playtime, date) values ('dokieran7', 67, '1:27', '2022-09-29');
|
||||
insert into game (username, score, playtime, date) values ('pdrinkel8', 84, '10:37', '2021-12-18');
|
||||
insert into game (username, score, playtime, date) values ('pdrinkel8', 14, '19:14', '2022-01-31');
|
||||
insert into game (username, score, playtime, date) values ('pdrinkel8', 21, '19:04', '2022-03-08');
|
||||
insert into game (username, score, playtime, date) values ('amelladew9', 46, '2:34', '2022-04-18');
|
||||
insert into game (username, score, playtime, date) values ('amelladew9', 78, '9:33', '2022-09-10');
|
||||
insert into game (username, score, playtime, date) values ('amelladew9', 82, '11:19', '2022-11-29');
|
||||
insert into game (user_id, score, playtime, date) values ('1', 74, '19:59', '2022-07-19');
|
||||
insert into game (user_id, score, playtime, date) values ('1', 86, '20:32', '2022-11-24');
|
||||
insert into game (user_id, score, playtime, date) values ('1', 68, '10:41', '2022-03-24');
|
||||
insert into game (user_id, score, playtime, date) values ('2', 39, '5:55', '2022-06-01');
|
||||
insert into game (user_id, score, playtime, date) values ('2', 20, '9:23', '2022-03-12');
|
||||
insert into game (user_id, score, playtime, date) values ('2', 28, '23:45', '2022-04-01');
|
||||
insert into game (user_id, score, playtime, date) values ('2', 44, '18:43', '2022-06-24');
|
||||
insert into game (user_id, score, playtime, date) values ('3', 92, '14:54', '2022-11-06');
|
||||
insert into game (user_id, score, playtime, date) values ('3', 73, '0:45', '2022-07-26');
|
||||
insert into game (user_id, score, playtime, date) values ('3', 27, '2:49', '2022-02-03');
|
||||
insert into game (user_id, score, playtime, date) values ('4', 26, '2:32', '2022-07-19');
|
||||
insert into game (user_id, score, playtime, date) values ('4', 12, '17:03', '2022-04-25');
|
||||
insert into game (user_id, score, playtime, date) values ('4', 6, '8:49', '2021-12-03');
|
||||
insert into game (user_id, score, playtime, date) values ('4', 22, '22:27', '2022-03-02');
|
||||
insert into game (user_id, score, playtime, date) values ('5', 94, '1:04', '2022-10-19');
|
||||
insert into game (user_id, score, playtime, date) values ('5', 2, '2:14', '2022-04-06');
|
||||
insert into game (user_id, score, playtime, date) values ('5', 21, '17:18', '2022-06-03');
|
||||
insert into game (user_id, score, playtime, date) values ('6', 33, '16:01', '2022-02-02');
|
||||
insert into game (user_id, score, playtime, date) values ('6', 27, '7:03', '2022-02-06');
|
||||
insert into game (user_id, score, playtime, date) values ('6', 62, '0:45', '2022-11-15');
|
||||
insert into game (user_id, score, playtime, date) values ('7', 12, '8:54', '2022-06-29');
|
||||
insert into game (user_id, score, playtime, date) values ('7', 63, '16:01', '2022-11-05');
|
||||
insert into game (user_id, score, playtime, date) values ('7', 29, '0:46', '2022-10-01');
|
||||
insert into game (user_id, score, playtime, date) values ('8', 67, '1:27', '2022-09-29');
|
||||
insert into game (user_id, score, playtime, date) values ('8', 84, '10:37', '2021-12-18');
|
||||
insert into game (user_id, score, playtime, date) values ('8', 14, '19:14', '2022-01-31');
|
||||
insert into game (user_id, score, playtime, date) values ('9', 21, '19:04', '2022-03-08');
|
||||
insert into game (user_id, score, playtime, date) values ('9', 46, '2:34', '2022-04-18');
|
||||
insert into game (user_id, score, playtime, date) values ('9', 78, '9:33', '2022-09-10');
|
||||
insert into game (user_id, score, playtime, date) values ('9', 82, '11:19', '2022-11-29');
|
||||
Loading…
Add table
Add a link
Reference in a new issue