9.3 KiB
9.3 KiB
Net-Games 数据库设计文档
版本: v2.0
更新日期: 2026-04-09
数据库: SQLite (开发/生产)
1. 技术选型
| 环境 | 数据库 | ORM | 说明 |
|---|---|---|---|
| 开发/生产 | SQLite | SQLAlchemy | 零配置,文件存储,适合当前规模 |
选择理由:
- 单机部署,无需外部数据库服务
- 数据量小(用户<1000,房间实时<100)
- 备份简单(复制文件即可)
- 未来可无缝迁移到PostgreSQL
2. 数据库文件
/home/ubuntu/nanocode/net-games/
├── net_games_auth.db # 主数据库(生产)
└── instance/
└── net_games_auth.db # Flask实例目录(开发)
3. 表结构设计
3.1 users - 用户表
存储注册用户信息和游戏积分。
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username VARCHAR(80) UNIQUE NOT NULL, -- 登录用户名(唯一)
nickname VARCHAR(80), -- 显示昵称(默认同用户名)
password_hash VARCHAR(200) NOT NULL, -- 密码哈希
role VARCHAR(20) DEFAULT 'user', -- 角色: admin/user
game_scores TEXT DEFAULT '{}', -- JSON格式各游戏积分
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_login TIMESTAMP
);
game_scores JSON格式:
{
"doudizhu": 100,
"chinese_chess": 50
}
Python模型 (server.py):
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
nickname = db.Column(db.String(80), nullable=True)
password_hash = db.Column(db.String(200), nullable=False)
role = db.Column(db.String(20), default='user')
game_scores = db.Column(db.Text, default='{}')
created_at = db.Column(db.DateTime, default=db.func.current_timestamp())
def get_game_score(self, game_id):
scores = json.loads(self.game_scores or '{}')
return scores.get(game_id, 0)
def add_game_score(self, game_id, points):
scores = json.loads(self.game_scores or '{}')
scores[game_id] = scores.get(game_id, 0) + points
self.game_scores = json.dumps(scores)
return scores[game_id]
默认用户:
| 用户名 | 密码 | 昵称 | 角色 |
|---|---|---|---|
| admin | abcd1234 | 管理员 | admin |
| caixianming | cxm123456 | 蔡叔叔 | user |
3.2 内存数据 vs 持久化数据
内存中维护(运行时):
| 数据 | 存储位置 | 说明 |
|---|---|---|
| 房间列表 | RoomManager._rooms | Dict[room_id, Room] |
| 玩家映射 | socket_player_map | Dict[socket_id, player_id] |
| 用户映射 | user_socket_map | Dict[user_id, socket_id] |
| 活跃用户 | active_usernames | Dict[username, player_id] |
| 用户房间 | user_room_map | Dict[username, room_id] |
持久化存储(SQLite):
| 数据 | 表 | 说明 |
|---|---|---|
| 用户信息 | users | 账号、密码、积分 |
注意: 房间和玩家数据仅在内存中维护,游戏结束后房间被清理。如需持久化游戏记录,需要额外设计GameRecord表。
4. 积分系统设计
4.1 积分规则(斗地主)
| 角色 | 胜利 | 失败 |
|---|---|---|
| 地主 | +6分 | -4分 |
| 农民 | +3分 | -2分 |
AI玩家不计积分,仅人类玩家累计积分。
4.2 积分更新流程
def calculate_and_update_scores(room, winner_id):
score_changes = {}
for pid, player in game.players.items():
if player.is_ai:
score_changes[pid] = {'change': 0, 'is_ai': True}
continue
is_lord = (pid == game.lord_id)
is_winner = (pid == winner_id)
# 计算积分变动
if is_lord:
change = 6 if is_winner else -4
else:
change = 3 if is_winner else -2
# 更新数据库
db_user = User.query.filter_by(username=player.name).first()
if db_user:
new_total = db_user.add_game_score('doudizhu', change)
db.session.commit()
score_changes[pid] = {
'change': change,
'total': new_total,
'is_ai': False
}
return score_changes
4.3 查询积分示例
# 获取用户斗地主积分
user = User.query.filter_by(username='蔡叔叔').first()
score = user.get_game_score('doudizhu') # 返回: 100
# 获取所有游戏积分
scores = json.loads(user.game_scores) # 返回: {'doudizhu': 100, ...}
5. 预留表设计(未来扩展)
5.1 game_records - 游戏记录表(预留)
用于保存游戏历史记录和回放数据。
CREATE TABLE game_records (
id VARCHAR(32) PRIMARY KEY,
room_id VARCHAR(32) NOT NULL,
game_type VARCHAR(20) NOT NULL,
started_at TIMESTAMP NOT NULL,
ended_at TIMESTAMP,
duration_seconds INTEGER,
-- 玩家信息 (JSON数组)
players JSON NOT NULL,
/* 格式:
[
{"player_id": "xxx", "name": "玩家A", "role": "landlord",
"is_ai": false, "score_change": 6},
{"player_id": "ai_1", "name": "AI-规则", "role": "farmer",
"is_ai": true, "ai_type": "rule", "score_change": -3}
]
*/
-- 结果
winner_id VARCHAR(32),
result_type VARCHAR(20), -- normal/surrender/timeout
-- 回放数据 (压缩存储)
replay_data BLOB, -- JSON序列化后 gzip 压缩
-- 统计
total_turns INTEGER,
max_combo INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
5.2 ai_usage - AI调用记录表(预留)
用于监控AI调用成本和性能。
CREATE TABLE ai_usage (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ai_type VARCHAR(20) NOT NULL, -- deepseek/rule/minimax
model_name VARCHAR(50), -- deepseek-chat
room_id VARCHAR(32),
game_type VARCHAR(20),
-- Token用量
input_tokens INTEGER,
output_tokens INTEGER,
total_tokens INTEGER,
-- 性能
latency_ms INTEGER,
-- 成本估算 (美元)
estimated_cost DECIMAL(10,6),
-- 调试信息
request_prompt TEXT,
response_text TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
5.3 rooms - 房间历史表(预留)
如需持久化房间信息,可创建此表。
CREATE TABLE rooms (
id VARCHAR(32) PRIMARY KEY,
room_code VARCHAR(10) UNIQUE,
game_type VARCHAR(20),
status VARCHAR(20), -- waiting/playing/ended/closed
created_at TIMESTAMP,
started_at TIMESTAMP,
ended_at TIMESTAMP,
max_players INTEGER,
config JSON,
winner_id VARCHAR(32),
final_state JSON,
is_active BOOLEAN DEFAULT TRUE
);
6. 数据库操作示例
6.1 初始化数据库
# server.py
with app.app_context():
db.create_all() # 创建所有表
init_default_users() # 创建默认用户
6.2 常用查询
# 用户认证
user = User.query.filter_by(username='caixianming').first()
if user and user.check_password('password'):
login_user(user)
# 获取排行榜
top_players = User.query.filter(
User.game_scores != '{}'
).order_by(
User.id # 简化排序,实际需解析JSON
).limit(10).all()
# 更新积分
user = User.query.filter_by(username='蔡叔叔').first()
new_score = user.add_game_score('doudizhu', 6)
db.session.commit()
6.3 数据库备份
# 备份SQLite数据库
cp /home/ubuntu/nanocode/net-games/net_games_auth.db \
/home/ubuntu/nanocode/net-games/backups/net_games_auth_$(date +%Y%m%d).db
7. 索引设计
-- 用户查询优化
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_role ON users(role);
-- 预留:游戏记录查询
-- CREATE INDEX idx_records_game_type ON game_records(game_type);
-- CREATE INDEX idx_records_created ON game_records(created_at DESC);
-- CREATE INDEX idx_records_winner ON game_records(winner_id);
-- 预留:AI用量查询
-- CREATE INDEX idx_ai_usage_time ON ai_usage(created_at);
-- CREATE INDEX idx_ai_usage_type ON ai_usage(ai_type);
8. 数据保留策略
| 数据类型 | 当前策略 | 未来规划 |
|---|---|---|
| 用户数据 | 永久保留 | 永久保留 |
| 积分记录 | 实时计算,无历史 | 可考虑添加积分变动日志 |
| 房间数据 | 内存存储,游戏结束即清理 | 如需持久化,添加rooms表 |
| 游戏记录 | 不保存 | 如需回放,添加game_records表 |
| AI调用记录 | 不保存 | 如需成本控制,添加ai_usage表 |
9. 更新日志
| 日期 | 版本 | 变更内容 |
|---|---|---|
| 2026-04-09 | v2.0 | 更新为实际实现,当前仅使用users表,其他为预留设计 |
| 2026-04-08 | v1.0 | 初始设计,包含完整ER图和多表设计 |
10. 总结
当前实现 (v2.0):
- 极简设计,仅使用
users表存储用户信息和积分 - 房间和玩家数据全部在内存中管理
- 适合当前小规模部署
未来扩展方向:
- 添加
game_records表保存游戏历史 - 添加
ai_usage表监控AI成本 - 添加
rooms表持久化房间信息 - 如需更复杂功能,迁移到PostgreSQL
文档版本: v2.0
最后更新: 2026-04-09
数据库文件: net_games_auth.db