django models索引和约束
Django 的 Meta 类支持索引(Indexes)和约束(Constraints),用于优化查询性能并确保数据完整性。
(一)索引 (indexes)
索引的作用是加速查询 ,特别是在 WHERE 条件中经常被筛选的字段上添加索引,可以提高查询效率。
python
class Meta:
indexes = [
models.Index(fields=['transaction_time']), # 给 transaction_time 建立索引,加速按时间查询
models.Index(fields=['user', 'transaction_type']), # 复合索引,提高按用户 + 交易类型的查询速度
]
1. 单字段索引
python
models.Index(fields=['transaction_time'])
- 作用 :加速按
transaction_time进行查询,如:
python
Transaction.objects.filter(transaction_time__gte="2024-01-01")
- 适用场景 :时间查询,如获取某个时间段内的交易记录。
2. 复合索引
python
models.Index(fields=['user', 'transaction_type'])
- 作用 :加速
user和transaction_type组合查询,如:
python
Transaction.objects.filter(user=user_obj, transaction_type="withdrawal")
- 适用场景 :多条件查询优化 ,例如:
- 先按
user筛选,再按transaction_type过滤。
- 先按
💡 索引优化建议
- 单独索引适用于高频筛选字段 (如
user、created_at)。 - 复合索引适用于组合查询 ,避免多个
WHERE条件导致的性能下降。
(二)唯一约束 (UniqueConstraint)
用于防止数据重复,确保某些字段组合具有唯一性。
python
models.UniqueConstraint(
fields=['user', 'transaction_time'],
name='unique_user_transaction'
)
- 作用 :确保同一个用户在同一时间只能有一条交易记录。
- 防止的问题:避免误操作导致同一时间重复创建交易。
💡 示例
python
Transaction.objects.create(user=user, amount=100, transaction_time="2024-03-20 10:00:00")
Transaction.objects.create(user=user, amount=50, transaction_time="2024-03-20 10:00:00")
# ❌ 抛出 IntegrityError,违反唯一约束
(三)检查约束 (CheckConstraint)
用于自定义数据验证规则,在数据库层面确保数据有效性。
python
models.CheckConstraint(
check=models.Q(amount__gt=0),
name='positive_amount'
)
- 作用 :确保
amount必须大于 0,防止存入负数或 0。 - 防止的问题 :防止用户提交负金额 或0(无意义的交易)。
💡 示例
python
Transaction.objects.create(user=user, amount=-50)
# ❌ 抛出 IntegrityError,违反 `positive_amount` 约束
(四)总结
| 功能 | 代码 | 作用 |
|---|---|---|
| 单字段索引 | models.Index(fields=['transaction_time']) |
加速按时间查询 |
| 复合索引 | models.Index(fields=['user', 'transaction_type']) |
加速用户 + 交易类型的查询 |
| 唯一约束 | models.UniqueConstraint(fields=['user', 'transaction_time'], name='unique_user_transaction') |
确保同一用户同一时间不能有重复交易 |
| 检查约束 | models.CheckConstraint(check=models.Q(amount__gt=0), name='positive_amount') |
确保 amount 大于 0 |
🚀 最佳实践
- 索引优化查询,减少数据库扫描,提高查询速度。
- 唯一约束防止重复数据 ,避免手动
filter().exists()逻辑。 - 检查约束保护数据完整性,从根本上防止错误数据进入数据库。
适用于 Django + PostgreSQL / MySQL 项目,提升数据一致性和查询效率!