I am currently working on a widget-based website, built entirely on user socialization. Since a reputation system pays off for attracting users, I decided to implement one of these.
Now, I would like to hear some solutions on how should this be implemented the right way (take, for example, Foursquare’s badge system).
Basically, I need to be able to do the following:
- have a badges table, where I can add, edit and delete badges;
- be able to enable and disable a badge;
- be able to introduce a new badge, but without writing new code – simply give some parameters to the add badge form regarding what should be followed in order for a user to receive a badge;
- be able to give badges in real time – meaning that whenever a user accomplishes whatever it needs to receive a badge, the system should know immediately to give the badge to that user;
- also, the system should not be overloaded with “badge listeners” – I believe interrogating each user request with every badge requirements is time consuming;
These being said, I would like to hear your opinions on how to implement the right way a badge system (logic, database schema, methods etc.)
This sounds like a massive project. Complexity will rise pretty fast no matter if you want it or not.
First thing I would do is start by creating documentation for API.
When you have documentation, you can plot requirements for your project. The things you wrote in question is some kind of requirements, but too abstract, too big picture like.
When you have requirements, you start to think about software engineering and structure.
In this step, splitting things apart in my opinion is the way to go. This will make things easier to manage. Finding bottlenecks bugs, and so on.
I don’t know what will be the trigger in your system for ‘if user should receive a badge’. So I’m taking foursquare analogy.
To be fair, the guys are doing amazing job to process all these requests in real time. I mean, it looks like they are checking if I should receive a badge on every request. So my check in is triggering some algorithm on server side to review my checkin and badges history, badge rules, mach them together, create my deserved badge and show my new badge in response. Sounds a lot right? Well, it is!
I don’t believe that they are doing all this work in parallel. This would be too much work for a server. Although, my fourquare badge is not interacting with any other user (much easier), so parallel processing is not out of the question.
So first idea for how foursquare could work. Load balancer forwards my request to not heavy loaded server. And there all job is done in paralel. The more the load, the more the servers are fired up. Do all calculation for badges on the fly using only slave database. Present to user his badge and send this data back to master db. This is possible, because badges are not interacting between different users. One badge – one user history needed.
Another solution would be to use map – reduce. Use message broker to process badge reviews in parallel. You receive a request. Send message to message broker. Message is landing on multiple workers where one worker is checking only one specific badge rules against user history. In the end, calculation would be done much faster.
About db structure. I think there is no way around of going through all db to actually find out if user should receive a badge or not. I would go with simple, straight forward way of handling this. Just create good structured db using foreign keys, proper column types, indexes in right places and you will be fine. Build stable ground, and optimize only when it is needed.
If you really eager to do optimization in the start of the project (that I think is a bad idea), I would keep all badge related data in separated tables. One table for one badge with all specific columns related to that badge.
Example would be: badge_restaurants (user_id, badge_id, current_level, checkin_count). To receive new restaurant badge you would need to check only if user did checkin_count + 1 >= needed qty and you are free to not look any further.
Of course, this is not perfect solution. More abstraction can be added to get it done in more sophisticated way (not create hundreds of tables). Still, more complex badges will push you to create more complex solutions.
Database & Live-updating:
create a table with columns as conditions
answers – votes – featured answer etc…
each time a user makes a submission or when users vote (client-side scripting for send), they are awarded a point/ponts (numerical increments in table columns).
on return value(client-side scripting for retrieve), based on conditional statements that are associated with the table columns, a badge is earned.
if votes = 50, achieve heplful badge
if featured = 10, achieve top contributor badge
by client-side scripting I mean ajax or json, Im not sure how you would go about scripting a live feed application
You could consider using the Drupal module User Badges or even looking at how it sets its schema up.
the first thing you should do it to have the proper structure for your project then start developing it… you’ll have many issues for sure but you can ask anytime because your post here is just general and any answer won’t help in your case.
but your idea is great 🙂