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 项目,提升数据一致性和查询效率!