4.3 KiB
4.3 KiB
Supabase Count 查询使用指南
基本语法
在 Supabase 中,有几种方式可以获取记录数量:
1. 使用 count 选项(推荐)
// 基本用法
const response = await supa
.from('table_name')
.select('*', { count: 'exact' })
.execute()
// 结果在 response.count 中
const totalCount = response.count
2. count 选项的类型
// exact: 精确计数(较慢,但准确)
.select('*', { count: 'exact' })
// estimated: 估算计数(较快,但可能不准确)
.select('*', { count: 'estimated' })
// planned: 计划计数(最快,但最不准确)
.select('*', { count: 'planned' })
实际应用示例
修改前(低效方式)
// ❌ 不推荐:获取所有数据然后计算长度
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
问题:
- 需要传输所有数据
- 浪费网络带宽
- 客户端处理负担重
- 性能差
修改后(高效方式)
// ✅ 推荐:直接在数据库层面计数
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
优势:
- 只传输计数结果
- 数据库层面计算,效率高
- 网络传输量小
- 客户端处理简单
教师仪表板中的应用
完整实现
// 总作业数
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 | 低 |
最佳实践
- 统计查询使用 count:当只需要数量时,总是使用 count
- 选择合适的 count 类型:一般情况用 'exact'
- 多条件分别查询:不同条件的计数分别查询,避免复杂的客户端过滤
- 错误处理:始终检查 response.count 是否为 null
- 并行查询:多个独立的 count 查询可以并行执行
// 并行执行多个 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()
])
这样既提高了性能,又简化了代码逻辑!