如何实施徽章?

发布于 2024-09-08 02:29:25 字数 276 浏览 4 评论 0原文

我已经考虑过实现徽章(就像 Stack Overflow 上的徽章一样),并且认为如果没有 Windows 服务,这会很困难,但如果可能的话,我想避免这种情况。

我想出了一个实施一些例子的计划:

  • Audobiographer:检查个人资料中的所有字段是否都已填写。
  • 评论者:发表评论时检查评论数是否等于10,如果是则授予徽章。
  • 好答案:投票时检查投票分数是否为 25 或更高。

如何在数据库中实现这一点?或者其他方式会更好吗?

I've given some thought to implementing badges (just like the badges here on Stack Overflow) and think it would be difficult without Windows services, but I'd like to avoid that if possible.

I came up with a plan to implement some examples:

  • Audobiographer: Check if all fields in the profile is filled out.
  • Commentor: When making a comment check if the number of comments equal 10, if so award the badge.
  • Good Answer: When voting up check to see if vote score is 25 or higher.

How could this be implemented in the database? Or would another way be better?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

在风中等你 2024-09-15 02:29:26

类似于 Stackoverflow 的实现实际上比您描述的要简单得多,基于团队偶尔丢弃的一些信息。

在数据库中,您只需存储一组 BadgeID-UserID 对来跟踪谁拥有什么(以及一个计数或 rowID 以允许某些徽章获得多个奖励)。

在应用程序中,每种徽章类型都有一个工作对象。该对象位于缓存中,当缓存过期时,工作器运行自己的逻辑来确定谁应该获得徽章并进行更新,然后将其重新插入到缓存中:

public abstract class BadgeJob
{
    protected BadgeJob()
    {
        //start cycling on initialization
        Insert();
    }

    //override to provide specific badge logic
    protected abstract void AwardBadges();

    //how long to wait between iterations
    protected abstract TimeSpan Interval { get; }

    private void Callback(string key, object value, CacheItemRemovedReason reason)
    {
        if (reason == CacheItemRemovedReason.Expired)
        {
            this.AwardBadges();
            this.Insert();
        }
    }

    private void Insert()
    {
        HttpRuntime.Cache.Add(this.GetType().ToString(),
            this,
            null,
            Cache.NoAbsoluteExpiration,
            this.Interval,
            CacheItemPriority.Normal,
            this.Callback);
    }
}

具体实现:

public class CommenterBadge : BadgeJob
{
    public CommenterBadge() : base() { }

    protected override void AwardBadges()
    {
        //select all users who have more than x comments 
        //and dont have the commenter badge
        //add badges
    }

    //run every 10 minutes
    protected override TimeSpan Interval
    {
        get { return new TimeSpan(0,10,0); }
    }
}

A similar-to-Stackoverflow implementation is actually a lot simpler than you have described, based on bits of info dropped by the team every once in awhile.

In the database, you simply store a collection of BadgeID-UserID pairs to track who has what (and a count or a rowID to allow multiple awards for some badges).

In the application, there is a worker object for each badge type. The object is in cache, and when the cache expires, the worker runs its own logic for determining who should get the badge and making the updates, and then it re-inserts itself into the cache:

public abstract class BadgeJob
{
    protected BadgeJob()
    {
        //start cycling on initialization
        Insert();
    }

    //override to provide specific badge logic
    protected abstract void AwardBadges();

    //how long to wait between iterations
    protected abstract TimeSpan Interval { get; }

    private void Callback(string key, object value, CacheItemRemovedReason reason)
    {
        if (reason == CacheItemRemovedReason.Expired)
        {
            this.AwardBadges();
            this.Insert();
        }
    }

    private void Insert()
    {
        HttpRuntime.Cache.Add(this.GetType().ToString(),
            this,
            null,
            Cache.NoAbsoluteExpiration,
            this.Interval,
            CacheItemPriority.Normal,
            this.Callback);
    }
}

And a concrete implementation:

public class CommenterBadge : BadgeJob
{
    public CommenterBadge() : base() { }

    protected override void AwardBadges()
    {
        //select all users who have more than x comments 
        //and dont have the commenter badge
        //add badges
    }

    //run every 10 minutes
    protected override TimeSpan Interval
    {
        get { return new TimeSpan(0,10,0); }
    }
}
呆橘 2024-09-15 02:29:26

乔布斯。这是关键。按设定的时间间隔运行的进程外作业以检查您提到的条件。我认为您甚至不需要 Windows 服务,除非它需要一些外部资源来设置级别。我实际上认为 StackOverflow 也使用作业来进行计算。

Jobs. That is the key. Out of process jobs that run at set intervals to check the criteria that you mention. I don't think you even need to have a windows service unless it requires some external resources to set the levels. I actually think StackOverflow uses jobs as well for their calculations.

甜味超标? 2024-09-15 02:29:26

您可以使用触发器并检查更新或插入,然后如果满足您的条件则添加徽章。这样处理起来就显得比较少了。在 3、2、1 中开始猛击扳机……

You could use triggers and check upon update or insert, then if your conditions are met add badge. That would handle it pretty seem less. Commence the trigger bashing in 3, 2, 1...

策马西风 2024-09-15 02:29:26

评论必须存储在数据库中吗?那么我认为有两种主要方法可以做到这一点。

1)当用户登录时,您会获得评论数。这显然不是理想的方法,因为计数可能需要很长时间

2)当用户发布评论时,您可以进行计数,然后将计数与使用详细信息一起存储,或者您可以执行一个触发器,在评论时执行已添加。然后,触发器将获取新创建的评论的详细信息,获取用户 ID,获取计数并将其针对用户存储在某种表中。

我喜欢触发器的想法,因为您的程序可以返回而无需等待 sql server 执行其操作。

comments must be stored within the database right? then i think there are two main ways to do this.

1) when a user logs in you get a count of the comments. this is obvisously not the desired approach as the count could take a lot of time

2) when a user posts a comment you could either do a count then and store the count with the use details or you could do a trigger which executes when a comment is added. the trigger would then get the details of the newly created comment, grab the user id, get a count and store that against the user in a table of some sort.

i like the idea of a trigger as your program can return w/out waiting for sql server to do its stuff.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文