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

158 lines
4.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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()
])
```
这样既提高了性能,又简化了代码逻辑!