-
Всем привет.
Возникла задача - реализовать простейший счет (что-то было сделано, увеличиваем счетчик на единицу). Счетчик не имеет ни одной связанной модели. Не вижу ничего проще чем
class Counter(models.Model):
pass
и добавление записей -
не счет, а счетчик*
-
Ну если порядок цифр не имеет значения то да.
Если же нужно было чтобы номера шли по порядку то чтонить типаclass Counter(models.Model):
count = models.IntegerField( default = 0 )
def save():
self.count+=1
models.Model.save(self) -
Таблица с добавлением записей плоха тем, что будет бесконечно расти, и ее будет все тяжелее считать. А в некоторых случаях (в зависимости от БД) и тяжелее обновлять из-за пересчета индексов. Плюс место она будет занимать сильно несоразмерно своей функции.
Решение с
count += 1не будет работать из-за race condition'ов: два процесса в начале работы считали счетчик со значением 1. Оба процесса сделают из него 2, хотя в результате должно быть 3.В базе это удобно делать, если это PostgreSQL или Oracle (про sqlite не знаю). Там есть прямой объект "sequence", который как раз гарантирует увеличение на 1 при каждом обращении. А если нужно более универсальное решение, то я бы просто в файл писал цифру, залочивая этот файл на всю операцию считывания-увеличения-записи. По скорости это особенно заметно быть не должно...
-
Решение с count += 1 не будет работать из-за race condition'ов: два процесса в начале работы считали счетчик со значением 1. Оба процесса сделают из него 2, хотя в результате должно быть 3.Это как пример. А реально поможет простейший SQL:
UPDATE app_counter SET counter=counter+1 -
В файл писать не получится, потому что могут быть тысячи операция в секунду. Счетчик нужен для внутренней статистики, для подсчета определенных операций (например, обращение к какому-либо view или число раз, когда был произведен session cleanup - да что угодно). То есть, нужен максимально быстро увеличивать счет на единицу в условиях единовременного доступа
-
Если даные не настролько критично терять, то используйте memcached для хранения и обновления данных.
Если критично, то периодически сливайте из него данные в БД, либо используйте memcachedDB
С точки зрения нагрузок - единственное оптимальное решение. -
В файл писать не получится, потому что могут быть тысячи операция в секунду.
Я боюсь ошибиться в порядках, но запись в базу будет определенно медленней в десятки или сотни раз. Файл из одного блока, который все равно постоянно будет висеть в кеше — это очень быстро, на самом деле. Только разместить его стоит на отдельном разделе, где отключить запись
atime. Хотя я подозреваю, что и без этого он вполне справится.

