From 5b6951eef25e76e4cbb566ea1783dd2bd7561a40 Mon Sep 17 00:00:00 2001 From: zheng020 Date: Thu, 28 May 2026 12:11:22 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E7=82=B9=E8=B5=9E=E6=A0=87=E7=AD=BE?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- .../status_text标签系统设计方案.md | 91 +++++++++++++++---- 2 files changed, 74 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 73076b2..ae2758c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,5 +23,5 @@ node_modules package-lock.json # Added by code-review-graph .code-review-graph/ - -.claude \ No newline at end of file +.claude/ +hookify.*.local.md \ No newline at end of file diff --git a/backend/docs/AI-Chat-Service/status_text标签系统设计方案.md b/backend/docs/AI-Chat-Service/status_text标签系统设计方案.md index eabcb98..fb053a3 100644 --- a/backend/docs/AI-Chat-Service/status_text标签系统设计方案.md +++ b/backend/docs/AI-Chat-Service/status_text标签系统设计方案.md @@ -108,13 +108,14 @@ // pkg/service/social_service.go func (s *SocialService) GetMyLikedAssets(ctx context.Context, req *pbSocial.GetMyLikedAssetsRequest) (*pbSocial.GetMyLikedAssetsResponse, error) { - // 1. 获取用户点赞作品列表 + // 1. 获取用户点赞作品列表(JOIN exhibition 获取 start_time,避免 N+1) items, total, hasMore := s.getLikedAssetsList(ctx, userID, page, pageSize) + assetIDs := extractAssetIDs(items) // 2. 批量获取用户点赞时间 likedAtMap := s.batchGetUserLikedAtMap(ctx, userID, assetIDs) - // 3. 批量获取作品排名 + // 3. 批量获取作品排名(排名数据变化不频繁,可加缓存) rankMap := s.batchGetAssetRanks(ctx, assetIDs) // 4. 批量获取过去1小时新增点赞 @@ -132,42 +133,51 @@ func (s *SocialService) GetMyLikedAssets(ctx context.Context, req *pbSocial.GetM } ``` +**性能优化说明:** + +| 优化项 | 优化前 | 优化后 | 收益 | +|--------|--------|--------|------| +| exhibition 查询 | 循环内逐条查询(N 次) | JOIN 一次获取 | 30 次查询 → 1 次 | +| 排名查询 | - | 批量 IN 查询 | 1 次 | +| 小时级新增点赞 | - | 批量聚合查询 | 1 次 | + +**关键索引建议:** +- `likes.asset_id + likes.created_at`(联合索引,时间窗口聚合) +- `likes.asset_id + likes.created_at + user_id`(用户点赞后新增统计) +- `exhibitions.asset_id + exhibitions.deleted_at`(JOIN 优化) + ### 4.3 status_text 计算函数 ```go func computeStatusText(item *LikedAssetItem) string { - // T0: 眼光拉满 - 用户点赞后新增点赞≥50 且仍在展出 + // T0: 眼光拉满 if item.UserLikedCountAfter >= 50 && !item.IsExpired { return "眼光拉满" } // T1: 排名型 - if item.Rank >= 1 && item.Rank <= 5 { + switch { + case item.Rank >= 1 && item.Rank <= 5: return fmt.Sprintf("屠榜顶流Top%d", item.Rank) - } - if item.Rank > 5 && item.Rank <= 10 { + case item.Rank > 5 && item.Rank <= 10: return fmt.Sprintf("第%d爆款", item.Rank) - } - if item.Rank == 20 || item.Rank == 50 || item.Rank == 100 || item.Rank == 200 { + case item.Rank == 20 || item.Rank == 50 || item.Rank == 100 || item.Rank == 200: return fmt.Sprintf("排名破%d", item.Rank) } // T3/T4: 状态型 - if item.HourlyNewLikes >= 20 { + switch { + case item.HourlyNewLikes >= 20: return "火速破圈" - } - if item.HourlyNewLikes >= 10 { + case item.HourlyNewLikes >= 10: return "小爆出圈" - } - if item.HourlyNewLikes >= 5 { + case item.HourlyNewLikes >= 5: return "热度积累" - } - if item.HourlyNewLikes >= 0 { + case item.HourlyNewLikes >= 0: return "缓慢涨粉" + default: + return "潜力待挖" } - - // 默认 - return "潜力待挖" } ``` @@ -273,7 +283,50 @@ if (res.data && res.data.items) { --- -## 8. 附录 +## 8. 高并发性能评估 + +### 7.1 单请求成本 + +| 查询操作 | 次数 | 说明 | +|----------|------|------| +| 点赞列表 + exhibition JOIN | 1 | 批量获取 30 条 | +| 批量获取排名 | 1 | IN 查询 30 条 | +| 批量获取小时级新增 | 1 | IN + 时间聚合 | +| 批量获取点赞后新增 | 1 | IN + 时间聚合 | +| **总计** | **4 次** | | + +`computeStatusText` 计算复杂度为 O(1),耗时 < 1μs,可忽略。 + +### 7.2 并发容量估算 + +假设:单请求 DB 耗时 20ms,DB 连接池 500 + +``` +单个连接处理能力:1000ms / 20ms = 50,000 请求/秒/连接 +500 连接 × 50 = 25,000 理论上限 QPS + +10,000 并发用户 → 约 3,000-5,000 实际 QPS +``` + +### 7.3 必要配置 + +| 配置项 | 推荐值 | 说明 | +|--------|--------|------| +| DB 连接池 | 300-500 | 根据 DB 服务器规格调整 | +| 排名缓存 TTL | 60s | 排名数据变化不频繁 | +| 索引 | 必建 | 参见 4.2 节索引建议 | + +### 7.4 风险点 + +| 风险 | 缓解方案 | +|------|----------| +| 点赞时频繁触发查询 | 点赞后可异步计算 status_text,不阻塞主流程 | +| DB 连接池耗尽 | 限流 + 连接池监控 | +| 慢查询 | 确保索引生效,定期 EXPLAIN 分析 | + +--- + +## 9. 附录 ### 8.1 标签文案汇总