我正在构建Django应用,我想在主页上显示一些统计信息,例如交易总数,成功交易的百分比,每日活跃用户数等。
由于性能原因,我不想每次用户请求主页时都在视图中计算这些值。我想到了两种可能的解决方案。
(1)创建多个单记录表
为每个统计信息创建一个表,例如:
from django.db import models
class LastSuccessfulTransactionDate(models.Model):
date = models.DateTimeField()
class TotalTransactionAmount(models.Model):
total_amount = models.DecimalField(max_digits=8, decimal_places=2)
# ...
并确保每个表中仅存在一条记录。
(2)创建具有键值数据的表
class Statistics(models.Model):
key = models.CharField(max_length=100)
value = models.TextField()
并通过执行以下操作保存数据:
from datetime import datetime
from decimal import Decimal
import pickle
statistics = {
'last_successful_transaction_date': datetime(2010, 2, 3),
'total_transaction_amount': Decimal('1234.56'),
}
for k, v in statistics.items():
try:
s = Statistics.objects.get(key=k)
except Statistics.DoesNotExist:
s = Statistics(key=k)
s.value = base64.b64encode(pickle.dumps(v, pickle.HIGHEST_PROTOCOL)).decode()
s.save()
并通过以下方式检索:
for s in Statistics.objects.all():
k = s.key
v = pickle.loads(base64.b64decode(s.value.encode()))
print(k, v)
在这两种情况下,数据都将不时地通过cron作业进行更新(它们不必非常精确)。
对我来说,解决方案(2)看起来更好,因为要显示主页,我只需要从Statistics
表中获取数据,而不是从许多单记录表中获取数据。是否有针对此问题的建议解决方案?谢谢
答案 0 :(得分:0)
如果使用的是property descriptor,则是更好的解决方案。您可以将键值对直接存储在JSONField中。尝试这样:
# model
class Statistics(models.Model):
records = JSONField()
# usage
statistics = {
'last_successful_transaction_date': datetime(2010, 2, 3),
'total_transaction_amount': Decimal('1234.56'),
}
Statistics.objects.create(records=statistics)
Statistics.objects.filter(records__last_successful_transaction_date= datetime(2010, 2, 3)) # Running query
s = Statistics.objects.filter(records__last_successful_transaction_date= datetime(2010, 2, 3)).first()
new_statistics = {
'last_successful_transaction_date': datetime(2012, 2, 3),
'total_transaction_amount': Decimal('1234.50'),
}
records = s.records
records.update(new_statistics)
s.records = records
s.save()