2026-06-12 01:21:33 +08:00

473 lines
28 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 使用 utf8mb4 连接字符集,保证中文注释、中文名称和 emoji 在导入时不被降级。
CREATE DATABASE IF NOT EXISTS hyapp_game DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE hyapp_game;
CREATE TABLE IF NOT EXISTS game_platforms (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码',
platform_name VARCHAR(128) NOT NULL COMMENT '平台名称',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
api_base_url VARCHAR(512) NOT NULL DEFAULT '' COMMENT 'API 基准 URL',
adapter_type VARCHAR(64) NOT NULL DEFAULT '' COMMENT '适配器类型',
callback_secret_ciphertext VARCHAR(1024) NOT NULL DEFAULT '' COMMENT '回调密钥密文',
callback_ip_whitelist JSON NULL COMMENT '回调IP白名单',
adapter_config JSON NULL COMMENT '适配器配置',
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序权重,数值越小越靠前',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, platform_code)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏平台表';
CREATE TABLE IF NOT EXISTS game_catalog (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
game_id VARCHAR(96) NOT NULL COMMENT '游戏 ID',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码',
provider_game_id VARCHAR(128) NOT NULL COMMENT '提供方游戏 ID',
game_name VARCHAR(128) NOT NULL COMMENT '游戏名称',
category VARCHAR(64) NOT NULL DEFAULT '' COMMENT '分类',
icon_url VARCHAR(512) NOT NULL DEFAULT '' COMMENT '图标 URL',
cover_url VARCHAR(512) NOT NULL DEFAULT '' COMMENT '封面 URL',
launch_mode VARCHAR(32) NOT NULL DEFAULT 'h5_popup' COMMENT '启动模式',
orientation VARCHAR(32) NOT NULL DEFAULT 'portrait' COMMENT '屏幕方向',
safe_height INT NOT NULL DEFAULT 0 COMMENT '游戏安全高',
min_coin BIGINT NOT NULL DEFAULT 0 COMMENT '最小金币',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序权重,数值越小越靠前',
tags JSON NULL COMMENT '标签',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, game_id),
UNIQUE KEY uk_game_provider(app_code, platform_code, provider_game_id),
KEY idx_game_platform_status(app_code, platform_code, status, sort_order)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏目录表';
CREATE TABLE IF NOT EXISTS game_display_rules (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
rule_id VARCHAR(96) NOT NULL COMMENT '规则 ID',
game_id VARCHAR(96) NOT NULL COMMENT '游戏 ID',
scene VARCHAR(64) NOT NULL COMMENT '场景',
region_id BIGINT NOT NULL DEFAULT 0 COMMENT '区域 ID',
language VARCHAR(32) NOT NULL DEFAULT '' COMMENT '语言',
platform VARCHAR(16) NOT NULL DEFAULT '' COMMENT '平台',
visible TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否可见',
enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '启用',
sort_order INT NOT NULL DEFAULT 0 COMMENT '排序权重,数值越小越靠前',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, rule_id),
KEY idx_game_display(app_code, scene, region_id, visible, sort_order)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏展示规则表';
CREATE TABLE IF NOT EXISTS game_launch_sessions (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
session_id VARCHAR(96) NOT NULL COMMENT '会话 ID',
user_id BIGINT NOT NULL COMMENT '用户 ID',
display_user_id VARCHAR(32) NOT NULL COMMENT '展示用户 ID',
room_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '房间 ID',
region_id BIGINT NOT NULL DEFAULT 0 COMMENT '用户启动游戏时的区域 ID',
scene VARCHAR(64) NOT NULL COMMENT '场景',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码',
game_id VARCHAR(96) NOT NULL COMMENT '游戏 ID',
provider_game_id VARCHAR(128) NOT NULL COMMENT '提供方游戏 ID',
launch_token_hash VARCHAR(128) NOT NULL COMMENT '启动令牌哈希值',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
expires_at_ms BIGINT NOT NULL COMMENT '过期时间UTC epoch ms',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, session_id),
KEY idx_game_launch_user(app_code, user_id, created_at_ms),
KEY idx_game_launch_recent(app_code, user_id, scene, created_at_ms, game_id),
KEY idx_game_launch_token(app_code, launch_token_hash)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏启动会话表';
CREATE TABLE IF NOT EXISTS game_orders (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
order_id VARCHAR(96) NOT NULL COMMENT '订单 ID',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码',
provider_order_id VARCHAR(160) NOT NULL COMMENT '提供方订单 ID',
provider_round_id VARCHAR(160) NOT NULL DEFAULT '' COMMENT '提供方轮次 ID',
game_id VARCHAR(96) NOT NULL COMMENT '游戏 ID',
provider_game_id VARCHAR(128) NOT NULL COMMENT '提供方游戏 ID',
user_id BIGINT NOT NULL COMMENT '用户 ID',
room_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '房间 ID',
region_id BIGINT NOT NULL DEFAULT 0 COMMENT '用户启动游戏时的区域 ID',
op_type VARCHAR(32) NOT NULL COMMENT 'op类型',
coin_amount BIGINT NOT NULL COMMENT '金币数量',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
wallet_transaction_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '钱包交易 ID',
wallet_balance_after BIGINT NOT NULL DEFAULT 0 COMMENT '钱包余额后',
request_hash VARCHAR(128) NOT NULL COMMENT '请求哈希值',
raw_payload_ref VARCHAR(256) NOT NULL DEFAULT '' COMMENT '原始负载外部引用',
failure_code VARCHAR(64) NOT NULL DEFAULT '' COMMENT '失败编码',
failure_message VARCHAR(256) NOT NULL DEFAULT '' COMMENT '失败消息',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, order_id),
UNIQUE KEY uk_game_provider_order(app_code, platform_code, provider_order_id),
KEY idx_game_order_user_time(app_code, user_id, created_at_ms),
KEY idx_game_order_round(app_code, platform_code, provider_round_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏钱包订单表';
CREATE TABLE IF NOT EXISTS game_dice_matches (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
match_id VARCHAR(96) NOT NULL COMMENT '骰子局 ID',
game_id VARCHAR(96) NOT NULL COMMENT '内部游戏 ID',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码快照',
provider_game_id VARCHAR(128) NOT NULL COMMENT '提供方游戏 ID 快照',
room_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '房间 ID',
region_id BIGINT NOT NULL DEFAULT 0 COMMENT '用户区域 ID',
min_players INT NOT NULL COMMENT '最少开局人数',
max_players INT NOT NULL COMMENT '最多参与人数',
current_players INT NOT NULL DEFAULT 0 COMMENT '当前参与人数',
stake_coin BIGINT NOT NULL COMMENT '单人下注金币',
round_no INT NOT NULL DEFAULT 1 COMMENT '轮次',
status VARCHAR(32) NOT NULL COMMENT '局状态',
result VARCHAR(64) NOT NULL DEFAULT '' COMMENT '局结果',
join_deadline_ms BIGINT NOT NULL DEFAULT 0 COMMENT '加入截止时间UTC epoch ms',
ready_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '匹配完成时间UTC epoch ms',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
settled_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '结算时间UTC epoch ms',
canceled_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '取消时间UTC epoch ms',
fee_bps INT NOT NULL DEFAULT 500 COMMENT '本局平台抽水万分比快照',
pool_bps INT NOT NULL DEFAULT 100 COMMENT '本局奖池入池万分比快照',
match_mode VARCHAR(32) NOT NULL DEFAULT '' COMMENT '匹配模式 human/robot',
forced_result VARCHAR(32) NOT NULL DEFAULT '' COMMENT '机器人局强制结果,首胜保护或奖池不足时使用',
pool_delta_coin BIGINT NOT NULL DEFAULT 0 COMMENT '本局对奖池的净变化',
PRIMARY KEY(app_code, match_id),
KEY idx_game_dice_room_active(app_code, room_id, status, created_at_ms),
KEY idx_game_dice_status_time(app_code, status, updated_at_ms, match_id),
KEY idx_game_dice_waiting(app_code, game_id, stake_coin, status, created_at_ms, match_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='骰子游戏局表';
CREATE TABLE IF NOT EXISTS game_dice_participants (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
match_id VARCHAR(96) NOT NULL COMMENT '骰子局 ID',
user_id BIGINT NOT NULL COMMENT '用户 ID',
participant_type VARCHAR(32) NOT NULL DEFAULT 'user' COMMENT '参与者类型 user/robot',
seat_no INT NOT NULL COMMENT '座位号',
status VARCHAR(32) NOT NULL COMMENT '参与状态',
stake_coin BIGINT NOT NULL COMMENT '下注金币',
dice_points_json JSON NULL COMMENT '骰子点数',
rps_gesture VARCHAR(32) NOT NULL DEFAULT '' COMMENT '石头剪刀布预选手势',
result VARCHAR(32) NOT NULL DEFAULT '' COMMENT '参与结果',
payout_coin BIGINT NOT NULL DEFAULT 0 COMMENT '返奖金币',
debit_order_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '下注订单 ID',
payout_order_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '派奖订单 ID',
refund_order_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '退款订单 ID',
balance_after BIGINT NOT NULL DEFAULT 0 COMMENT '最近一次钱包账后余额',
joined_at_ms BIGINT NOT NULL COMMENT '加入时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, match_id, user_id),
UNIQUE KEY uk_game_dice_seat(app_code, match_id, seat_no),
KEY idx_game_dice_participant_user(app_code, user_id, updated_at_ms),
KEY idx_game_dice_participant_status(app_code, match_id, status, seat_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='骰子游戏参与者表';
-- 骰子旧库已经存在 match/participant 表时CREATE TABLE 不会补列;这里把 H5 实时流程依赖的阶段、费率、机器人和奖池快照列幂等补齐。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND COLUMN_NAME = 'ready_at_ms') = 0,
'ALTER TABLE game_dice_matches ADD COLUMN ready_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT ''匹配完成时间UTC epoch ms'' AFTER join_deadline_ms',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND COLUMN_NAME = 'canceled_at_ms') = 0,
'ALTER TABLE game_dice_matches ADD COLUMN canceled_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT ''取消时间UTC epoch ms'' AFTER settled_at_ms',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND COLUMN_NAME = 'fee_bps') = 0,
'ALTER TABLE game_dice_matches ADD COLUMN fee_bps INT NOT NULL DEFAULT 500 COMMENT ''本局平台抽水万分比快照'' AFTER canceled_at_ms',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND COLUMN_NAME = 'pool_bps') = 0,
'ALTER TABLE game_dice_matches ADD COLUMN pool_bps INT NOT NULL DEFAULT 100 COMMENT ''本局奖池入池万分比快照'' AFTER fee_bps',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND COLUMN_NAME = 'match_mode') = 0,
'ALTER TABLE game_dice_matches ADD COLUMN match_mode VARCHAR(32) NOT NULL DEFAULT '''' COMMENT ''匹配模式 human/robot'' AFTER pool_bps',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND COLUMN_NAME = 'forced_result') = 0,
'ALTER TABLE game_dice_matches ADD COLUMN forced_result VARCHAR(32) NOT NULL DEFAULT '''' COMMENT ''机器人局强制结果,首胜保护或奖池不足时使用'' AFTER match_mode',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND COLUMN_NAME = 'pool_delta_coin') = 0,
'ALTER TABLE game_dice_matches ADD COLUMN pool_delta_coin BIGINT NOT NULL DEFAULT 0 COMMENT ''本局对奖池的净变化'' AFTER forced_result',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 参与者类型是机器人扩展的事实字段;旧局默认真人,避免历史数据阻塞查询和结算。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_participants' AND COLUMN_NAME = 'participant_type') = 0,
'ALTER TABLE game_dice_participants ADD COLUMN participant_type VARCHAR(32) NOT NULL DEFAULT ''user'' COMMENT ''参与者类型 user/robot'' AFTER user_id',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- rock 真实猜拳复用自研局表,但胜负来自参与者预选手势;旧库补空值,后续新局强制写入。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_participants' AND COLUMN_NAME = 'rps_gesture') = 0,
'ALTER TABLE game_dice_participants ADD COLUMN rps_gesture VARCHAR(32) NOT NULL DEFAULT '''' COMMENT ''石头剪刀布预选手势'' AFTER dice_points_json',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 全服等待队列按 app/game/stake/status 命中;旧库没有这个索引时,高并发匹配会退化成扫描历史局。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_matches' AND INDEX_NAME = 'idx_game_dice_waiting') = 0,
'ALTER TABLE game_dice_matches ADD INDEX idx_game_dice_waiting (app_code, game_id, stake_coin, status, created_at_ms, match_id)',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_dice_participants' AND INDEX_NAME = 'idx_game_dice_participant_status') = 0,
'ALTER TABLE game_dice_participants ADD INDEX idx_game_dice_participant_status (app_code, match_id, status, seat_no)',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CREATE TABLE IF NOT EXISTS game_self_game_configs (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
game_id VARCHAR(96) NOT NULL COMMENT '自研游戏 ID',
status VARCHAR(32) NOT NULL DEFAULT 'active' COMMENT '配置状态',
stake_options_json JSON NULL COMMENT '可下注金币档位',
fee_bps INT NOT NULL DEFAULT 500 COMMENT '平台抽水万分比',
pool_bps INT NOT NULL DEFAULT 100 COMMENT '奖池入池万分比',
min_players INT NOT NULL DEFAULT 2 COMMENT '最少开局人数',
max_players INT NOT NULL DEFAULT 2 COMMENT '最多参与人数',
robot_enabled TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否启用机器人补位',
robot_match_wait_ms BIGINT NOT NULL DEFAULT 3000 COMMENT '等待真人后机器人补位毫秒数',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, game_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='自研游戏配置表';
CREATE TABLE IF NOT EXISTS game_self_game_pools (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
game_id VARCHAR(96) NOT NULL COMMENT '自研游戏 ID',
balance_coin BIGINT NOT NULL DEFAULT 0 COMMENT '机器人共享奖池余额',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, game_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='自研游戏机器人奖池表';
CREATE TABLE IF NOT EXISTS game_self_game_pool_transactions (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
adjustment_id VARCHAR(96) NOT NULL COMMENT '奖池流水 ID',
game_id VARCHAR(96) NOT NULL COMMENT '自研游戏 ID',
match_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '关联骰子局 ID',
user_id BIGINT NOT NULL DEFAULT 0 COMMENT '关联真实用户 ID',
direction VARCHAR(16) NOT NULL COMMENT '方向 in/out',
amount_coin BIGINT NOT NULL COMMENT '变化金币',
reason VARCHAR(128) NOT NULL DEFAULT '' COMMENT '变化原因',
balance_after BIGINT NOT NULL COMMENT '变化后奖池余额',
created_by BIGINT NOT NULL DEFAULT 0 COMMENT '后台操作者或系统用户',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
PRIMARY KEY(app_code, adjustment_id),
KEY idx_game_pool_tx_game_time(app_code, game_id, created_at_ms),
KEY idx_game_pool_tx_match(app_code, match_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='自研游戏奖池流水表';
CREATE TABLE IF NOT EXISTS game_self_game_robots (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
game_id VARCHAR(96) NOT NULL COMMENT '自研游戏 ID',
user_id BIGINT NOT NULL COMMENT '真实 App 机器人用户 ID',
status VARCHAR(32) NOT NULL DEFAULT 'active' COMMENT '机器人状态',
created_by_admin_id BIGINT NOT NULL DEFAULT 0 COMMENT '创建管理员 ID',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
last_used_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '最近一次被匹配补位时间UTC epoch ms',
used_count BIGINT NOT NULL DEFAULT 0 COMMENT '累计被匹配补位次数',
PRIMARY KEY(app_code, game_id, user_id),
KEY idx_game_robot_status(app_code, game_id, status, updated_at_ms, user_id),
KEY idx_game_robot_random_pool(app_code, status, user_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='自研游戏机器人登记表';
-- 机器人使用时间和累计次数只用于后台观察随机命中分布;旧表补默认 0避免存量机器人资料读取失败。
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_self_game_robots' AND COLUMN_NAME = 'last_used_at_ms') = 0,
'ALTER TABLE game_self_game_robots ADD COLUMN last_used_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT ''最近一次被匹配补位时间UTC epoch ms'' AFTER updated_at_ms',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_self_game_robots' AND COLUMN_NAME = 'used_count') = 0,
'ALTER TABLE game_self_game_robots ADD COLUMN used_count BIGINT NOT NULL DEFAULT 0 COMMENT ''累计被匹配补位次数'' AFTER last_used_at_ms',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_self_game_robots' AND INDEX_NAME = 'idx_game_robot_rotation') > 0,
'ALTER TABLE game_self_game_robots DROP INDEX idx_game_robot_rotation',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @ddl := IF(
(SELECT COUNT(*) FROM information_schema.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'game_self_game_robots' AND INDEX_NAME = 'idx_game_robot_random_pool') = 0,
'ALTER TABLE game_self_game_robots ADD INDEX idx_game_robot_random_pool (app_code, status, user_id)',
'SELECT 1'
);
PREPARE stmt FROM @ddl;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CREATE TABLE IF NOT EXISTS game_explore_winners (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
win_id VARCHAR(96) NOT NULL COMMENT 'Explore Square 播报 ID',
game_code VARCHAR(64) NOT NULL COMMENT 'App H5 入口 key例如 game_dice/game_rock',
game_id VARCHAR(96) NOT NULL COMMENT '来源游戏 ID',
user_id BIGINT NOT NULL COMMENT '获胜用户 ID',
display_name VARCHAR(128) NOT NULL DEFAULT '' COMMENT '展示昵称快照',
avatar_url VARCHAR(512) NOT NULL DEFAULT '' COMMENT '展示头像快照',
coin_amount BIGINT NOT NULL COMMENT '获胜金币数',
won_at_ms BIGINT NOT NULL COMMENT '获胜时间UTC epoch ms',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, win_id),
KEY idx_game_explore_winners_time(app_code, won_at_ms, win_id),
KEY idx_game_explore_winners_game(app_code, game_code, won_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Explore Square 游戏获胜播报表';
CREATE TABLE IF NOT EXISTS game_callback_logs (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
callback_id VARCHAR(96) NOT NULL COMMENT '回调 ID',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码',
operation VARCHAR(64) NOT NULL COMMENT '操作',
request_id VARCHAR(96) NOT NULL DEFAULT '' COMMENT '链路请求 ID用于排查问题',
provider_request_id VARCHAR(160) NOT NULL DEFAULT '' COMMENT '提供方请求 ID',
signature_valid TINYINT(1) NOT NULL DEFAULT 0 COMMENT '签名有效',
request_hash VARCHAR(128) NOT NULL COMMENT '请求哈希值',
response_code VARCHAR(64) NOT NULL DEFAULT '' COMMENT '响应编码',
response_body_hash VARCHAR(128) NOT NULL DEFAULT '' COMMENT '响应正文哈希值',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
PRIMARY KEY(app_code, callback_id),
KEY idx_game_callback_platform_time(app_code, platform_code, created_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏回调日志表';
CREATE TABLE IF NOT EXISTS game_repair_orders (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
repair_id VARCHAR(96) NOT NULL COMMENT '修复 ID',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码',
provider_order_id VARCHAR(160) NOT NULL COMMENT '提供方订单 ID',
reason VARCHAR(128) NOT NULL COMMENT '原因',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
operator_admin_id BIGINT NOT NULL DEFAULT 0 COMMENT '操作管理员 ID',
attempts INT NOT NULL DEFAULT 0 COMMENT '尝试次数',
next_run_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '下一个运行时间UTC epoch ms',
last_error_code VARCHAR(64) NOT NULL DEFAULT '' COMMENT '最后错误编码',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, repair_id),
UNIQUE KEY uk_game_repair_provider_order(app_code, platform_code, provider_order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏修复订单表';
CREATE TABLE IF NOT EXISTS game_level_event_outbox (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
event_id VARCHAR(160) NOT NULL COMMENT '事件幂等 ID',
order_id VARCHAR(96) NOT NULL COMMENT '订单 ID',
user_id BIGINT NOT NULL COMMENT '用户 ID',
game_id VARCHAR(96) NOT NULL COMMENT '游戏 ID',
provider_order_id VARCHAR(160) NOT NULL COMMENT '提供方订单 ID',
provider_round_id VARCHAR(160) NOT NULL DEFAULT '' COMMENT '提供方轮次 ID',
coin_amount BIGINT NOT NULL COMMENT '金币数量',
wallet_transaction_id VARCHAR(96) NOT NULL COMMENT '钱包交易 ID',
payload_json JSON NULL COMMENT '业务负载 JSON 快照',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
attempt_count INT NOT NULL DEFAULT 0 COMMENT '尝试次数',
next_retry_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '下一次重试时间UTC epoch ms',
locked_by VARCHAR(128) NOT NULL DEFAULT '' COMMENT '当前锁定 worker',
locked_until_ms BIGINT NOT NULL DEFAULT 0 COMMENT '锁定截止时间UTC epoch ms',
failure_reason VARCHAR(255) NOT NULL DEFAULT '' COMMENT '失败原因',
occurred_at_ms BIGINT NOT NULL COMMENT '业务发生时间UTC epoch ms',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, event_id),
UNIQUE KEY uk_game_level_event_order(app_code, order_id),
KEY idx_game_level_event_pending(app_code, status, next_retry_at_ms, created_at_ms),
KEY idx_game_level_event_claim(app_code, status, locked_until_ms, next_retry_at_ms, created_at_ms, event_id),
KEY idx_game_level_event_claim_order(app_code, status, locked_until_ms, created_at_ms, event_id, next_retry_at_ms),
KEY idx_game_level_event_retention(app_code, status, updated_at_ms, event_id),
KEY idx_game_level_event_user(app_code, user_id, created_at_ms)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏等级事件 outbox 表';
CREATE TABLE IF NOT EXISTS game_outbox (
app_code VARCHAR(32) NOT NULL COMMENT '应用编码,用于多租户隔离',
event_id VARCHAR(160) NOT NULL COMMENT '事件幂等 ID',
event_type VARCHAR(64) NOT NULL COMMENT '事件类型',
order_id VARCHAR(96) NOT NULL COMMENT '订单 ID',
user_id BIGINT NOT NULL COMMENT '用户 ID',
platform_code VARCHAR(64) NOT NULL COMMENT '平台编码',
game_id VARCHAR(96) NOT NULL COMMENT '游戏 ID',
op_type VARCHAR(32) NOT NULL COMMENT '游戏改账方向',
coin_amount BIGINT NOT NULL COMMENT '金币数量',
payload_json JSON NOT NULL COMMENT '业务负载 JSON 快照',
status VARCHAR(32) NOT NULL COMMENT '业务状态',
worker_id VARCHAR(128) NOT NULL DEFAULT '' COMMENT 'MQ 投递 worker ID',
lock_until_ms BIGINT NOT NULL DEFAULT 0 COMMENT 'MQ 投递锁过期时间UTC epoch ms',
retry_count INT NOT NULL DEFAULT 0 COMMENT '重试次数',
next_retry_at_ms BIGINT NOT NULL DEFAULT 0 COMMENT '下一次 MQ 投递重试时间UTC epoch ms',
last_error VARCHAR(512) NOT NULL DEFAULT '' COMMENT '最后一次失败原因',
created_at_ms BIGINT NOT NULL COMMENT '创建时间UTC epoch ms',
updated_at_ms BIGINT NOT NULL COMMENT '更新时间UTC epoch ms',
PRIMARY KEY(app_code, event_id),
KEY idx_game_outbox_status_created(app_code, status, next_retry_at_ms, created_at_ms, event_id),
KEY idx_game_outbox_lock(app_code, status, lock_until_ms, created_at_ms, event_id),
KEY idx_game_outbox_retention(app_code, status, updated_at_ms, event_id),
KEY idx_game_outbox_order(app_code, order_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='游戏统计事件 outbox 表';