1. Michael Samoylov

    08.10.2008 09:35

    Всем привет.

    Возникла задача - реализовать простейший счет (что-то было сделано, увеличиваем счетчик на единицу). Счетчик не имеет ни одной связанной модели. Не вижу ничего проще чем
    class Counter(models.Model):
    pass
    и добавление записей
  2. Michael Samoylov

    08.10.2008 09:36

    не счет, а счетчик*
  3. gqbe.livejournal.com

    08.10.2008 09:39

    Ну если порядок цифр не имеет значения то да.
    Если же нужно было чтобы номера шли по порядку то чтонить типа
    class Counter(models.Model):
    count = models.IntegerField( default = 0 )
    def save():
    self.count+=1
    models.Model.save(self)
  4. Иван Сагалаев

    08.10.2008 12:12

    Таблица с добавлением записей плоха тем, что будет бесконечно расти, и ее будет все тяжелее считать. А в некоторых случаях (в зависимости от БД) и тяжелее обновлять из-за пересчета индексов. Плюс место она будет занимать сильно несоразмерно своей функции.

    Решение с count += 1 не будет работать из-за race condition'ов: два процесса в начале работы считали счетчик со значением 1. Оба процесса сделают из него 2, хотя в результате должно быть 3.

    В базе это удобно делать, если это PostgreSQL или Oracle (про sqlite не знаю). Там есть прямой объект "sequence", который как раз гарантирует увеличение на 1 при каждом обращении. А если нужно более универсальное решение, то я бы просто в файл писал цифру, залочивая этот файл на всю операцию считывания-увеличения-записи. По скорости это особенно заметно быть не должно...

  5. gqbe.livejournal.com

    08.10.2008 14:25

    Решение с count += 1 не будет работать из-за race condition'ов: два процесса в начале работы считали счетчик со значением 1. Оба процесса сделают из него 2, хотя в результате должно быть 3.
    Это как пример. А реально поможет простейший SQL:
    UPDATE app_counter SET counter=counter+1
  6. Michael Samoylov

    08.10.2008 14:40

    В файл писать не получится, потому что могут быть тысячи операция в секунду. Счетчик нужен для внутренней статистики, для подсчета определенных операций (например, обращение к какому-либо view или число раз, когда был произведен session cleanup - да что угодно). То есть, нужен максимально быстро увеличивать счет на единицу в условиях единовременного доступа
  7. Never

    08.10.2008 15:29

    Если даные не настролько критично терять, то используйте memcached для хранения и обновления данных.
    Если критично, то периодически сливайте из него данные в БД, либо используйте memcachedDB

    С точки зрения нагрузок - единственное оптимальное решение.
  8. Иван Сагалаев

    08.10.2008 15:32

    В файл писать не получится, потому что могут быть тысячи операция в секунду.

    Я боюсь ошибиться в порядках, но запись в базу будет определенно медленней в десятки или сотни раз. Файл из одного блока, который все равно постоянно будет висеть в кеше — это очень быстро, на самом деле. Только разместить его стоит на отдельном разделе, где отключить запись atime. Хотя я подозреваю, что и без этого он вполне справится.

bbcode