# Supabase Count 查询使用指南 ## 基本语法 在 Supabase 中,有几种方式可以获取记录数量: ### 1. 使用 count 选项(推荐) ```typescript // 基本用法 const response = await supa .from('table_name') .select('*', { count: 'exact' }) .execute() // 结果在 response.count 中 const totalCount = response.count ``` ### 2. count 选项的类型 ```typescript // exact: 精确计数(较慢,但准确) .select('*', { count: 'exact' }) // estimated: 估算计数(较快,但可能不准确) .select('*', { count: 'estimated' }) // planned: 计划计数(最快,但最不准确) .select('*', { count: 'planned' }) ``` ## 实际应用示例 ### 修改前(低效方式) ```typescript // ❌ 不推荐:获取所有数据然后计算长度 const response = await supa .from('ak_assignments') .select('id, status') .eq('teacher_id', userId) .execute() const totalCount = response.data?.length || 0 const completedCount = response.data?.filter(a => a.status === 'completed').length || 0 ``` **问题**: - 需要传输所有数据 - 浪费网络带宽 - 客户端处理负担重 - 性能差 ### 修改后(高效方式) ```typescript // ✅ 推荐:直接在数据库层面计数 const totalResponse = await supa .from('ak_assignments') .select('*', { count: 'exact' }) .eq('teacher_id', userId) .execute() const completedResponse = await supa .from('ak_assignments') .select('*', { count: 'exact' }) .eq('teacher_id', userId) .eq('status', 'completed') .execute() const totalCount = totalResponse.count || 0 const completedCount = completedResponse.count || 0 ``` **优势**: - 只传输计数结果 - 数据库层面计算,效率高 - 网络传输量小 - 客户端处理简单 ## 教师仪表板中的应用 ### 完整实现 ```typescript // 总作业数 const assignmentStatsResponse = await supa .from('ak_assignments') .select('*', { count: 'exact' }) .eq('teacher_id', currentUser) .execute() // 已完成作业数 const completedStatsResponse = await supa .from('ak_assignments') .select('*', { count: 'exact' }) .eq('teacher_id', currentUser) .eq('status', 'completed') .execute() // 待评阅作业数 const pendingStatsResponse = await supa .from('ak_assignments') .select('*', { count: 'exact' }) .eq('teacher_id', currentUser) .eq('status', 'submitted') .execute() // 学生总数 const studentStatsResponse = await supa .from('ak_users') .select('*', { count: 'exact' }) .eq('role', 'student') .execute() // 处理结果 stats.value = { total_assignments: assignmentStatsResponse.count || 0, completed_assignments: completedStatsResponse.count || 0, pending_review: pendingStatsResponse.count || 0, total_students: studentStatsResponse.count || 0 } ``` ## 性能对比 ### 数据量: 1000条记录 | 方式 | 网络传输 | 处理时间 | 内存使用 | |------|----------|----------|----------| | 获取全部数据 | ~100KB | ~200ms | 高 | | 使用 count | ~1KB | ~50ms | 低 | ### 数据量: 10000条记录 | 方式 | 网络传输 | 处理时间 | 内存使用 | |------|----------|----------|----------| | 获取全部数据 | ~1MB | ~2s | 很高 | | 使用 count | ~1KB | ~100ms | 低 | ## 最佳实践 1. **统计查询使用 count**:当只需要数量时,总是使用 count 2. **选择合适的 count 类型**:一般情况用 'exact' 3. **多条件分别查询**:不同条件的计数分别查询,避免复杂的客户端过滤 4. **错误处理**:始终检查 response.count 是否为 null 5. **并行查询**:多个独立的 count 查询可以并行执行 ```typescript // 并行执行多个 count 查询 const [totalResp, completedResp, pendingResp, studentResp] = await Promise.all([ supa.from('ak_assignments').select('*', { count: 'exact' }).eq('teacher_id', userId).execute(), supa.from('ak_assignments').select('*', { count: 'exact' }).eq('teacher_id', userId).eq('status', 'completed').execute(), supa.from('ak_assignments').select('*', { count: 'exact' }).eq('teacher_id', userId).eq('status', 'submitted').execute(), supa.from('ak_users').select('*', { count: 'exact' }).eq('role', 'student').execute() ]) ``` 这样既提高了性能,又简化了代码逻辑!