Проектирование базы данных для системы пользователя / баллов? (в Джанго) - PullRequest
1 голос
/ 25 марта 2010

Прежде всего, извините, если этот вопрос не подходит для StackOverflow. Я пытался сделать его максимально обобщенным.

Я хочу создать базу данных (MySQL, сайт под управлением Django), в которой есть пользователи, которым может быть выделено определенное количество баллов для различных типов действий - это совместная игра. Мои требования для получения:

  • количество баллов у пользователя
  • рейтинг пользователя по сравнению со всеми другими пользователями
  • и общая таблица лидеров (то есть все пользователи ранжируются в порядке очков)

Это то, что у меня есть, в моем файле Django models.py:

class SiteUser(models.Model):
    name = models.CharField(max_length=250 )
    email = models.EmailField(max_length=250 )
    date_added = models.DateTimeField(auto_now_add=True) 
    def points_total(self):
        points_added = PointsAdded.objects.filter(user=self)
        points_total = 0
        for point in points_added:
            points_total += point.points
        return points_total

class PointsAdded(models.Model):
    user = models.ForeignKey('SiteUser')
    action = models.ForeignKey('Action')
    date_added = models.DateTimeField(auto_now_add=True) 
    def points(self):
        points = Action.objects.filter(action=self.action)
        return points

class Action(models.Model):
    points = models.IntegerField()
    action = models.CharField(max_length=36)

Однако мне быстро становится ясно, что на самом деле довольно сложно (по крайней мере в терминах запросов Django) определить рейтинг пользователя и вернуть список лидеров пользователей. По крайней мере, я нахожу это жестким. Есть ли более элегантный способ сделать что-то подобное?

Этот вопрос , похоже, говорит о том, что у меня даже не должно быть отдельной таблицы баллов - что думают люди? Кажется более надежным иметь отдельные таблицы, но у меня нет большого опыта проектирования баз данных.

Ответы [ 2 ]

1 голос
/ 23 октября 2011

это старый, но я не уверен точно, почему у вас есть 2 отдельные таблицы (Очки добавлены и действие). Уже поздно, поэтому, возможно, мой разум не тикает, но кажется, что по какой-то причине вы просто разделили одну таблицу на две. Не похоже, что вы получаете какую-то выгоду от этого. Не похоже, что в этом есть отношение 1 ко многим, верно?

Итак, прежде всего, я бы объединил эти две таблицы. Во-вторых, вам, вероятно, лучше сохранить points_total в значение в вашей таблице site_user. Это то, на что, как мне кажется, пытается навязать Деметрий, но не сказал прямо. Таким образом, вместо выполнения всего этого дополнительного запроса (извлечение всего, что пользователь сделал в своей истории сайта - это дорого) + зацикливание (проходить через него еще дороже), вы можете просто перетащить его в одно поле. Это денормализует данные для большего блага.

Обязательно обновляйте значение каждый раз, когда добавляете что-то, что имеет баллы. Вы можете использовать сигнал django post_save, чтобы сделать это

0 голосов
/ 26 марта 2010

Немного сложнее сохранить точки в одной таблице, но это того стоит. Вы можете выполнять очень простые операции упорядочения / фильтрации, если вы рассчитали общее количество баллов по пользовательской модели. И вы можете считать итоги только тогда, когда что-то меняется (не каждый раз, когда вы хотите их показать). Просто вставьте некоторую логику проверки в сигналы post_save и убедитесь, что она покрыта тестами, и все хорошо.

p.s. денормализация в вики.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...