Files
akmon/doc_zhipao/supabase_count_usage_guide.md
2026-01-20 08:04:15 +08:00

4.3 KiB
Raw Permalink Blame History

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

最佳实践

  1. 统计查询使用 count:当只需要数量时,总是使用 count
  2. 选择合适的 count 类型:一般情况用 'exact'
  3. 多条件分别查询:不同条件的计数分别查询,避免复杂的客户端过滤
  4. 错误处理:始终检查 response.count 是否为 null
  5. 并行查询:多个独立的 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()
])

这样既提高了性能,又简化了代码逻辑!