2010-03-25 54 views
1

首先,很抱歉,如果這不是StackOverflow的適當問題。我儘量使其儘可能通用。爲用戶/積分系統設計數據庫? (在Django中)

我想創建一個擁有用戶的數據庫(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) 

然而,它的迅速b這對我來說很清楚,它確實相當複雜(至少在Django查詢條件下)來確定用戶的排名並返回用戶的排行榜。至少,我發現它很艱難。有沒有更優雅的方式來做這樣的事情?

This question似乎表明我甚至不應該有一個單獨的積分表 - 人們會怎麼想?有單獨的表格感覺更健壯,但我沒有太多的數據庫設計經驗。

回答

0

將點保存在同一張表中更加困難,但這完全值得。如果您在用戶模型上計算了總點數,則可以執行非常簡單的排序/篩選操作。而且只有當某些事情發生變化時(而不是每次你想展示它們)你都可以計算總數。只需將一些驗證邏輯放入post_save信號中,並確保使用測試覆蓋此邏輯,並且您很好。

p.s. denormalization上wiki。

1

這是舊的,但我不確定爲什麼你有2個單獨的表(添加點數&動作)。現在已經很晚了,所以也許我的大腦並沒有滴答滴答,但似乎你只是因爲某種原因將一張桌子分成了兩張。它似乎沒有從中獲得任何好處。這不是一對多的關係嗎?

所以首先,我會結合這兩個表。其次,你最好將points_total存儲到你的site_user表中的值。這是我認爲德米特里試圖暗示的,但沒有明確表示。這種方式而不是做這整個額外的查詢(拉動用戶在他的網站歷史上所做的一切都是昂貴的)+循環操作(經歷它更昂貴),你可以把它作爲一個領域。它是爲了獲得更大的利益而對數據進行非規範化處理。

只要確保在每次添加有點的東西時更新該值。您可以使用django的post_save信號來做到這一點