-- Enable Foreign Keys PRAGMA foreign_keys = ON; -- 1. Dimension: Players -- Stores persistent player information. -- Conflict resolution: UPSERT on steam_id_64. CREATE TABLE IF NOT EXISTS dim_players ( steam_id_64 TEXT PRIMARY KEY, uid INTEGER, -- 5E Platform ID username TEXT, avatar_url TEXT, domain TEXT, created_at INTEGER, -- Timestamp updated_at INTEGER, -- Timestamp last_seen_match_id TEXT, uuid TEXT, email TEXT, area TEXT, mobile TEXT, user_domain TEXT, username_audit_status INTEGER, accid TEXT, team_id INTEGER, trumpet_count INTEGER, profile_nickname TEXT, profile_avatar_audit_status INTEGER, profile_rgb_avatar_url TEXT, profile_photo_url TEXT, profile_gender INTEGER, profile_birthday INTEGER, profile_country_id TEXT, profile_region_id TEXT, profile_city_id TEXT, profile_language TEXT, profile_recommend_url TEXT, profile_group_id INTEGER, profile_reg_source INTEGER, status_status INTEGER, status_expire INTEGER, status_cancellation_status INTEGER, status_new_user INTEGER, status_login_banned_time INTEGER, status_anticheat_type INTEGER, status_flag_status1 TEXT, status_anticheat_status TEXT, status_flag_honor TEXT, status_privacy_policy_status INTEGER, status_csgo_frozen_exptime INTEGER, platformexp_level INTEGER, platformexp_exp INTEGER, steam_account TEXT, steam_trade_url TEXT, steam_rent_id TEXT, trusted_credit INTEGER, trusted_credit_level INTEGER, trusted_score INTEGER, trusted_status INTEGER, trusted_credit_status INTEGER, certify_id_type INTEGER, certify_status INTEGER, certify_age INTEGER, certify_real_name TEXT, certify_uid_list TEXT, certify_audit_status INTEGER, certify_gender INTEGER, identity_type INTEGER, identity_extras TEXT, identity_status INTEGER, identity_slogan TEXT, identity_list TEXT, identity_slogan_ext TEXT, identity_live_url TEXT, identity_live_type INTEGER, plus_is_plus INTEGER, user_info_raw TEXT ); CREATE INDEX IF NOT EXISTS idx_dim_players_uid ON dim_players(uid); -- 2. Dimension: Maps CREATE TABLE IF NOT EXISTS dim_maps ( map_id INTEGER PRIMARY KEY AUTOINCREMENT, map_name TEXT UNIQUE NOT NULL, map_desc TEXT ); -- 3. Fact: Matches CREATE TABLE IF NOT EXISTS fact_matches ( match_id TEXT PRIMARY KEY, match_code TEXT, map_name TEXT, start_time INTEGER, end_time INTEGER, duration INTEGER, winner_team INTEGER, -- 1 or 2 score_team1 INTEGER, score_team2 INTEGER, server_ip TEXT, server_port INTEGER, location TEXT, has_side_data_and_rating2 INTEGER, match_main_id INTEGER, demo_url TEXT, game_mode INTEGER, game_name TEXT, map_desc TEXT, location_full TEXT, match_mode INTEGER, match_status INTEGER, match_flag INTEGER, status INTEGER, waiver INTEGER, year INTEGER, season TEXT, round_total INTEGER, cs_type INTEGER, priority_show_type INTEGER, pug10m_show_type INTEGER, credit_match_status INTEGER, knife_winner INTEGER, knife_winner_role INTEGER, most_1v2_uid INTEGER, most_assist_uid INTEGER, most_awp_uid INTEGER, most_end_uid INTEGER, most_first_kill_uid INTEGER, most_headshot_uid INTEGER, most_jump_uid INTEGER, mvp_uid INTEGER, response_code INTEGER, response_message TEXT, response_status INTEGER, response_timestamp INTEGER, response_trace_id TEXT, response_success INTEGER, response_errcode INTEGER, treat_info_raw TEXT, round_list_raw TEXT, leetify_data_raw TEXT, data_source_type TEXT CHECK(data_source_type IN ('leetify', 'classic', 'unknown')), -- 'leetify' has economy data, 'classic' has detailed xyz processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX IF NOT EXISTS idx_fact_matches_time ON fact_matches(start_time); CREATE TABLE IF NOT EXISTS fact_match_teams ( match_id TEXT, group_id INTEGER, group_all_score INTEGER, group_change_elo REAL, group_fh_role INTEGER, group_fh_score INTEGER, group_origin_elo REAL, group_sh_role INTEGER, group_sh_score INTEGER, group_tid INTEGER, group_uids TEXT, PRIMARY KEY (match_id, group_id), FOREIGN KEY (match_id) REFERENCES fact_matches(match_id) ON DELETE CASCADE ); -- 4. Fact: Match Player Stats (Wide Table) -- Aggregated stats for a player in a specific match CREATE TABLE IF NOT EXISTS fact_match_players ( match_id TEXT, steam_id_64 TEXT, team_id INTEGER, -- 1 or 2 -- Basic Stats kills INTEGER DEFAULT 0, deaths INTEGER DEFAULT 0, assists INTEGER DEFAULT 0, headshot_count INTEGER DEFAULT 0, kd_ratio REAL, adr REAL, rating REAL, -- 5E Rating rating2 REAL, rating3 REAL, rws REAL, mvp_count INTEGER DEFAULT 0, elo_change REAL, rank_score INTEGER, is_win BOOLEAN, -- Advanced Stats (VIP/Plus) kast REAL, entry_kills INTEGER, entry_deaths INTEGER, awp_kills INTEGER, clutch_1v1 INTEGER, clutch_1v2 INTEGER, clutch_1v3 INTEGER, clutch_1v4 INTEGER, clutch_1v5 INTEGER, flash_assists INTEGER, flash_duration REAL, jump_count INTEGER, -- Utility Usage Stats (Parsed from round details) util_flash_usage INTEGER DEFAULT 0, util_smoke_usage INTEGER DEFAULT 0, util_molotov_usage INTEGER DEFAULT 0, util_he_usage INTEGER DEFAULT 0, util_decoy_usage INTEGER DEFAULT 0, damage_total INTEGER, damage_received INTEGER, damage_receive INTEGER, damage_stats INTEGER, assisted_kill INTEGER, awp_kill INTEGER, awp_kill_ct INTEGER, awp_kill_t INTEGER, benefit_kill INTEGER, day TEXT, defused_bomb INTEGER, end_1v1 INTEGER, end_1v2 INTEGER, end_1v3 INTEGER, end_1v4 INTEGER, end_1v5 INTEGER, explode_bomb INTEGER, first_death INTEGER, fd_ct INTEGER, fd_t INTEGER, first_kill INTEGER, flash_enemy INTEGER, flash_team INTEGER, flash_team_time REAL, flash_time REAL, game_mode TEXT, group_id INTEGER, hold_total INTEGER, id INTEGER, is_highlight INTEGER, is_most_1v2 INTEGER, is_most_assist INTEGER, is_most_awp INTEGER, is_most_end INTEGER, is_most_first_kill INTEGER, is_most_headshot INTEGER, is_most_jump INTEGER, is_svp INTEGER, is_tie INTEGER, kill_1 INTEGER, kill_2 INTEGER, kill_3 INTEGER, kill_4 INTEGER, kill_5 INTEGER, many_assists_cnt1 INTEGER, many_assists_cnt2 INTEGER, many_assists_cnt3 INTEGER, many_assists_cnt4 INTEGER, many_assists_cnt5 INTEGER, map TEXT, match_code TEXT, match_mode TEXT, match_team_id INTEGER, match_time INTEGER, per_headshot REAL, perfect_kill INTEGER, planted_bomb INTEGER, revenge_kill INTEGER, round_total INTEGER, season TEXT, team_kill INTEGER, throw_harm INTEGER, throw_harm_enemy INTEGER, uid INTEGER, year TEXT, sts_raw TEXT, level_info_raw TEXT, PRIMARY KEY (match_id, steam_id_64), FOREIGN KEY (match_id) REFERENCES fact_matches(match_id) ON DELETE CASCADE -- Intentionally not enforcing FK on steam_id_64 strictly to allow stats even if player dim missing, but ideally it should match. ); CREATE TABLE IF NOT EXISTS fact_match_players_t ( match_id TEXT, steam_id_64 TEXT, team_id INTEGER, kills INTEGER DEFAULT 0, deaths INTEGER DEFAULT 0, assists INTEGER DEFAULT 0, headshot_count INTEGER DEFAULT 0, kd_ratio REAL, adr REAL, rating REAL, rating2 REAL, rating3 REAL, rws REAL, mvp_count INTEGER DEFAULT 0, elo_change REAL, rank_score INTEGER, is_win BOOLEAN, kast REAL, entry_kills INTEGER, entry_deaths INTEGER, awp_kills INTEGER, clutch_1v1 INTEGER, clutch_1v2 INTEGER, clutch_1v3 INTEGER, clutch_1v4 INTEGER, clutch_1v5 INTEGER, flash_assists INTEGER, flash_duration REAL, jump_count INTEGER, damage_total INTEGER, damage_received INTEGER, damage_receive INTEGER, damage_stats INTEGER, assisted_kill INTEGER, awp_kill INTEGER, awp_kill_ct INTEGER, awp_kill_t INTEGER, benefit_kill INTEGER, day TEXT, defused_bomb INTEGER, end_1v1 INTEGER, end_1v2 INTEGER, end_1v3 INTEGER, end_1v4 INTEGER, end_1v5 INTEGER, explode_bomb INTEGER, first_death INTEGER, fd_ct INTEGER, fd_t INTEGER, first_kill INTEGER, flash_enemy INTEGER, flash_team INTEGER, flash_team_time REAL, flash_time REAL, game_mode TEXT, group_id INTEGER, hold_total INTEGER, id INTEGER, is_highlight INTEGER, is_most_1v2 INTEGER, is_most_assist INTEGER, is_most_awp INTEGER, is_most_end INTEGER, is_most_first_kill INTEGER, is_most_headshot INTEGER, is_most_jump INTEGER, is_svp INTEGER, is_tie INTEGER, kill_1 INTEGER, kill_2 INTEGER, kill_3 INTEGER, kill_4 INTEGER, kill_5 INTEGER, many_assists_cnt1 INTEGER, many_assists_cnt2 INTEGER, many_assists_cnt3 INTEGER, many_assists_cnt4 INTEGER, many_assists_cnt5 INTEGER, map TEXT, match_code TEXT, match_mode TEXT, match_team_id INTEGER, match_time INTEGER, per_headshot REAL, perfect_kill INTEGER, planted_bomb INTEGER, revenge_kill INTEGER, round_total INTEGER, season TEXT, team_kill INTEGER, throw_harm INTEGER, throw_harm_enemy INTEGER, uid INTEGER, year TEXT, sts_raw TEXT, level_info_raw TEXT, -- Utility Usage Stats (Parsed from round details) util_flash_usage INTEGER DEFAULT 0, util_smoke_usage INTEGER DEFAULT 0, util_molotov_usage INTEGER DEFAULT 0, util_he_usage INTEGER DEFAULT 0, util_decoy_usage INTEGER DEFAULT 0, PRIMARY KEY (match_id, steam_id_64), FOREIGN KEY (match_id) REFERENCES fact_matches(match_id) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS fact_match_players_ct ( match_id TEXT, steam_id_64 TEXT, team_id INTEGER, kills INTEGER DEFAULT 0, deaths INTEGER DEFAULT 0, assists INTEGER DEFAULT 0, headshot_count INTEGER DEFAULT 0, kd_ratio REAL, adr REAL, rating REAL, rating2 REAL, rating3 REAL, rws REAL, mvp_count INTEGER DEFAULT 0, elo_change REAL, rank_score INTEGER, is_win BOOLEAN, kast REAL, entry_kills INTEGER, entry_deaths INTEGER, awp_kills INTEGER, clutch_1v1 INTEGER, clutch_1v2 INTEGER, clutch_1v3 INTEGER, clutch_1v4 INTEGER, clutch_1v5 INTEGER, flash_assists INTEGER, flash_duration REAL, jump_count INTEGER, damage_total INTEGER, damage_received INTEGER, damage_receive INTEGER, damage_stats INTEGER, assisted_kill INTEGER, awp_kill INTEGER, awp_kill_ct INTEGER, awp_kill_t INTEGER, benefit_kill INTEGER, day TEXT, defused_bomb INTEGER, end_1v1 INTEGER, end_1v2 INTEGER, end_1v3 INTEGER, end_1v4 INTEGER, end_1v5 INTEGER, explode_bomb INTEGER, first_death INTEGER, fd_ct INTEGER, fd_t INTEGER, first_kill INTEGER, flash_enemy INTEGER, flash_team INTEGER, flash_team_time REAL, flash_time REAL, game_mode TEXT, group_id INTEGER, hold_total INTEGER, id INTEGER, is_highlight INTEGER, is_most_1v2 INTEGER, is_most_assist INTEGER, is_most_awp INTEGER, is_most_end INTEGER, is_most_first_kill INTEGER, is_most_headshot INTEGER, is_most_jump INTEGER, is_svp INTEGER, is_tie INTEGER, kill_1 INTEGER, kill_2 INTEGER, kill_3 INTEGER, kill_4 INTEGER, kill_5 INTEGER, many_assists_cnt1 INTEGER, many_assists_cnt2 INTEGER, many_assists_cnt3 INTEGER, many_assists_cnt4 INTEGER, many_assists_cnt5 INTEGER, map TEXT, match_code TEXT, match_mode TEXT, match_team_id INTEGER, match_time INTEGER, per_headshot REAL, perfect_kill INTEGER, planted_bomb INTEGER, revenge_kill INTEGER, round_total INTEGER, season TEXT, team_kill INTEGER, throw_harm INTEGER, throw_harm_enemy INTEGER, uid INTEGER, year TEXT, sts_raw TEXT, level_info_raw TEXT, -- Utility Usage Stats (Parsed from round details) util_flash_usage INTEGER DEFAULT 0, util_smoke_usage INTEGER DEFAULT 0, util_molotov_usage INTEGER DEFAULT 0, util_he_usage INTEGER DEFAULT 0, util_decoy_usage INTEGER DEFAULT 0, PRIMARY KEY (match_id, steam_id_64), FOREIGN KEY (match_id) REFERENCES fact_matches(match_id) ON DELETE CASCADE ); -- 5. Fact: Rounds CREATE TABLE IF NOT EXISTS fact_rounds ( match_id TEXT, round_num INTEGER, winner_side TEXT CHECK(winner_side IN ('CT', 'T', 'None')), win_reason INTEGER, -- Raw integer from source win_reason_desc TEXT, -- Mapped description (e.g. 'TargetBombed') duration REAL, end_time_stamp TEXT, ct_score INTEGER, t_score INTEGER, -- Leetify Specific ct_money_start INTEGER, t_money_start INTEGER, PRIMARY KEY (match_id, round_num), FOREIGN KEY (match_id) REFERENCES fact_matches(match_id) ON DELETE CASCADE ); -- 6. Fact: Round Events (The largest table) -- Unifies Kills, Bomb Events, etc. CREATE TABLE IF NOT EXISTS fact_round_events ( event_id TEXT PRIMARY KEY, -- UUID match_id TEXT, round_num INTEGER, event_type TEXT CHECK(event_type IN ('kill', 'bomb_plant', 'bomb_defuse', 'suicide', 'unknown')), event_time INTEGER, -- Seconds from round start -- Participants attacker_steam_id TEXT, victim_steam_id TEXT, assister_steam_id TEXT, flash_assist_steam_id TEXT, trade_killer_steam_id TEXT, -- Weapon & Context weapon TEXT, is_headshot BOOLEAN DEFAULT 0, is_wallbang BOOLEAN DEFAULT 0, is_blind BOOLEAN DEFAULT 0, is_through_smoke BOOLEAN DEFAULT 0, is_noscope BOOLEAN DEFAULT 0, -- Spatial Data (From RoundList) attacker_pos_x INTEGER, attacker_pos_y INTEGER, attacker_pos_z INTEGER, victim_pos_x INTEGER, victim_pos_y INTEGER, victim_pos_z INTEGER, -- Economy/Score Impact (From Leetify) score_change_attacker REAL, score_change_victim REAL, FOREIGN KEY (match_id, round_num) REFERENCES fact_rounds(match_id, round_num) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_round_events_match ON fact_round_events(match_id); CREATE INDEX IF NOT EXISTS idx_round_events_attacker ON fact_round_events(attacker_steam_id); -- 7. Fact: Round Player Economy/Status -- Snapshots of player state at round start/end CREATE TABLE IF NOT EXISTS fact_round_player_economy ( match_id TEXT, round_num INTEGER, steam_id_64 TEXT, side TEXT CHECK(side IN ('CT', 'T')), start_money INTEGER, equipment_value INTEGER, -- Inventory Summary main_weapon TEXT, has_helmet BOOLEAN, has_defuser BOOLEAN, -- Round Performance Summary (Leetify) round_performance_score REAL, PRIMARY KEY (match_id, round_num, steam_id_64), FOREIGN KEY (match_id, round_num) REFERENCES fact_rounds(match_id, round_num) ON DELETE CASCADE );