2009-09-08 40 views
8

Cho phép nói rằng tôi có khoảng 1.000.000 người dùng. Tôi muốn tìm hiểu vị trí của bất kỳ người dùng cụ thể nào và người dùng nào ở xung quanh anh ta. Người dùng có thể có được thành tích mới bất cứ lúc nào và nếu anh ta có thể thấy cập nhật thường trực của mình, điều đó sẽ tuyệt vời.Django: Cách tạo bảng xếp hạng

Thành thật mà nói, mọi cách tôi nghĩ về việc này sẽ tốn kém khủng khiếp về thời gian và/hoặc trí nhớ. Ý tưởng? Ý tưởng gần nhất của tôi cho đến nay là đặt hàng người dùng ngoại tuyến và tạo nhóm phần trăm, nhưng điều đó không thể hiển thị cho người dùng vị trí chính xác của người dùng.

Một số mã nếu giúp bạn django người:

class Alias(models.Model) : 
    awards = models.ManyToManyField('Award', through='Achiever') 

    @property 
    def points(self) : 
     p = cache.get('alias_points_' + str(self.id)) 
     if p is not None : return p 

     points = 0 
     for a in self.achiever_set.all() : 
      points += a.award.points * a.count 

     cache.set('alias_points_' + str(self.id), points, 60 * 60) # 1 hour 
     return points 

class Award(MyBaseModel): 
    owner_points = models.IntegerField(help_text="A non-normalized point value. Very subjective but try to be consistent. Should be proporional. 2x points = 2x effort (or skill)") 
    true_points = models.FloatField(help_text="The true value of this award. Recalculated with a cron job. Based on number of people who won it", editable=False, null=True) 

    @property 
    def points(self) : 
     if self.true_points : 
      # blend true_points into real points over 30 days 
      age = datetime.now() - self.created 
      blend_days = 30 
      if age > timedelta(days=blend_days) : 
       age = timedelta(days=blend_days) 
      num_days = 1.0 * age.days/blend_days 
      r = self.true_points * num_days + self.owner_points * (1 - num_days) 
      return int(r * 10)/10.0 

     else : 
      return self.owner_points 


class Achiever(MyBaseModel): 
    award = models.ForeignKey(Award) 
    alias = models.ForeignKey(Alias) 
    count = models.IntegerField(default=1) 

Trả lời

4

Tôi nghĩ Counterstrike giải quyết điều này bằng cách yêu cầu người dùng phải đáp ứng ngưỡng tối thiểu để trở nên xếp - bạn chỉ cần sắp xếp một cách chính xác 10% đầu hoặc bất cứ điều gì .

Nếu bạn muốn sắp xếp mọi người, hãy cân nhắc rằng bạn không cần phải sắp xếp chúng hoàn hảo: sắp xếp chúng thành 2 số liệu quan trọng. Với 1 triệu người dùng, bạn có thể cập nhật bảng thành tích cho 100 người dùng hàng đầu trong thời gian thực, 1000 người dùng tiếp theo lên 10 người dùng gần nhất, sau đó là số lượng người chơi lên gần 1% hoặc 10%. Bạn sẽ không nhảy từ vị trí 500.000 đến vị trí 99 trong một vòng.

Không có ý nghĩa của nó để có được bối cảnh 10 người dùng ở trên và bên dưới đặt 500.000 - thứ tự của quần chúng sẽ vô cùng hốt hoảng từ vòng sang vòng do phân phối mũ.

Chỉnh sửa: Hãy xem SO leaderboard. Bây giờ, hãy truy cập page 500 trong số 2500 (khoảng 20 phần trăm). Có bất kỳ điểm nào để nói với những người có đại diện '157' rằng 10 người ở hai bên họ cũng có đại diện '157' không? Bạn sẽ nhảy 20 vị trí một trong hai cách nếu đại diện của bạn đi lên hoặc xuống một điểm. Cực đoan hơn, đó là ngay bây giờ dưới 1056 trang (trong số 2538), hoặc 42% người dùng dưới cùng, được liên kết với đại diện 1. bạn nhận được thêm một điểm và bạn đã nhảy lên 1055 pages. Đó là khoảng 37.000 tăng xếp hạng. Nó có thể được mát mẻ để nói với họ "bạn có thể đánh bại 37k người nếu bạn nhận được một điểm nữa!" nhưng có vấn đề bao nhiêu con số đáng kể số 37k có?

Không có giá trị trong việc biết bạn bè của bạn trên một bậc thang cho đến khi bạn đã ở trên cùng, bởi vì bất cứ đâu nhưng trên cùng, có một số lượng áp đảo của chúng.

+0

một người nào đó vui lòng chỉnh sửa nội dung này để phù hợp hơn, tôi sẽ đi ngủ. –

+0

Tôi đã cố gắng cung cấp cho người dùng một mục tiêu bằng cách hiển thị cho họ những người ở trên họ để đánh bại, nhưng không quá xa để không thể truy cập được. –

+0

jitter về phía dưới cùng của phân phối sẽ tuyệt vời đến mức thậm chí lên hoặc xuống 1 điểm sẽ thả bạn hoặc thu được cho bạn vài nghìn địa điểm trong 1 triệu. bạn nên đo lường phân phối điểm của bạn trông như thế nào. –

0

Một triệu không phải là quá nhiều, tôi sẽ thử nó một cách dễ dàng đầu tiên. Nếu thuộc tính điểm là thứ bạn đang phân loại trên đó cần phải là cột cơ sở dữ liệu. Sau đó, bạn chỉ có thể làm một số điểm lớn hơn so với người trong câu hỏi để có được thứ hạng. Để có được những người khác gần một người được đề cập, bạn truy vấn những người có điểm cao hơn và sắp xếp giới hạn tăng dần lên số người bạn muốn.

Điều khó khăn sẽ tính toán các điểm khi lưu. Bạn cần sử dụng thời gian hiện tại làm hệ số tiền thưởng. Một điểm bây giờ cần phải chuyển thành một số ít hơn 1 điểm 5 ngày kể từ bây giờ. Nếu người dùng của bạn thường xuyên đạt được điểm, bạn sẽ cần phải tạo một hàng đợi để xử lý tải.

Các vấn đề liên quan