I have a bunch of contests a user can enter. At any time there are about 10 active contests. Every hour a new contest goes up and the oldest contest ends. I want to track how many contests in a row a user competes in. The only problem is that a user can enter contests out of order, but should still get credit as long as they compete in each contest before it ends.
I have worked on a few possible solutions, but each one seems to have terrible edge cases that are very difficult to detect. Am I missing something or is this just a pretty hard problem?
So basically I am keeping track of the last contest the user participated in by updating the user record when each contest ends. I then check if this contest matches the previously ended contest. If it does, I increment their contestStreak counter. If it doesn't, I reset the counter to 1. This seems like the best way to do it and I can't believe I didn't realize this before.
You could use the longest increasing subsequence of a given sequence (O(n^2)). There are also O(n) and O(n log n) methods.
You might also take a look at this question: Find the largest subset of it which form a sequence.
Related
How to optimally store the viewing time of an episode in the database? What I have done now is that as soon as the user starts an episode 1- At first, it is checked whether there is a user observation record in the table or not. 2- If there is, the time column will be updated with Ajax every second 3- If it does not exist, a record will be recorded and the viewing time will be recorded again in the table Note: This system is currently working well, but my question is, if, for example, a thousand people are watching the episodes at the same time, will the database not face a serious problem? Every second, four queries are sent by one person, and if a thousand people see it, this number reaches four thousand queries per second, what is the best solution? Does this system not cause failure?
A consideration is how accurate you want the viewing time to be.
You could for instance, write the viewing time to the session (only) and then persist it to the database every minute, or when the viewer navigates to a new page.
But, every second seems an unrealistic expectation since you have per second requests to your server coming in from every viewer.
So, consider what is reasonable. If it is just for your own stats then maybe 10 second increments is enough. If it is so that the user can leave and return to the exact second they left then again, possible, but probably unreasonable. I don't expect this to happen with youtube or netflix - there is normally some amount of overlap, which actually helps me remember where I got to.
Sorry if this has been covered - I've been looking for hours but I think I simply lack the vocabulary to search effectively.
I'm trying to figure out how I should store profile information for each user. By profile information I don't mean information like email and the like, but more their preferences regarding the site I'm working on.
It's a language learning site, and I want users to be able to save their "progress", giving them the option to flag a lesson as learned.
I also want to keep track of which exercises they have done, so that I can try to only give them exercises they haven't done (or when they've used up the available exercises, start from the least recent). I'm just not sure where to store all this information.
Should I have a lookup table linking users to lessons? I fear this will get huge as the number of users and tables increases. Seeing as its just a boolean, I considered giving each user an int (and later more ints as an array) where each bit represents a lesson, and performing bitwise operators on those numbers to get the information about which lessons they've saved... though that sounds like it could be cumbersome in the future.
As for remembering which exercises they've done, I fear this will lead to a huge amount of waste if I try to save it in mysql. Could I try to have this done on the user's computer using cookies, and anybody who has cookies disabled will simply have to deal with repeating exercise questions?
Maybe I should think about other tables and even other databases! I don't know!
Sorry for all the rambling nonsense. At the very least I'd appreciate some pointers towards what I need to read up on...
A lookup table between the users and the exercises is the simplest and most flexible, and you really shouldn't have to worry about the size of it. It'll have a user id, an exercise id, and some sort of progress variable, so (depending on your needs) that's probably going to be less than 10 bytes of space per row. 1 million rows wouldn't even take up 10MB of space.
I'd probably just have records only get created in the table once the user has made some sort of progress on a particular exercise. So if you ever try to look up a user's progress on an exercise and a row isn't found, that means that they haven't done anything on that exercise. That way you only need to create rows to represent progress, and it should keep the number fairly low overall.
You'll need a junction table to link each user to different exercises (many-to-many relationship):
user_id(int) exercise_id(int) learned(boolean)
You don't have to have entries for every possible combination, you can add each combination when a lesson is flagged as learned.
The bitwise method is going down a bad road, you'd need a bit for each lesson... it's not scalable.
Scenario is simple to describe, but might have a complex answer:
Imagine a case where you have one write only mysql database. Then you have about 5 or 6 read only databases. The write database has a count for a particular inventory. You have hundreds of thousands of users banging away at this particular inventory item, but only limited quantity. For argument's sake, say 10 items.
What's the best way to ensure that only 10 items get sold? If there is even a 200ms delta between the time the read-only slaves get updated, can't the integrity of the count go stale, thus selling inventory you do not have?
How would you solve/scale this problem?
The basic solution to concurrent users will probably cover this too. At some point in the "buy" transaction, you need to decrement the inventory (on the write-server). Through whatever method, enforce that inventory can't go below zero.
If there's one item left, and two people trying to buy it, one will be out of luck.
The replication latency is exactly the same thing. Two users see a product available, but by the time they try to buy it, it's gone. A good solution for that scenario covers both replication latency and a user simply snatching the last item out from under another user.
It all depends on when and what window you decide to lock the master table for the update.
A. If you have to be 100% sure an item will be attempted to be bought only when its surely available. You will have to lock the item for the particular user as soon as you list it to him (which means you will temporarily decrement the inventory stock)
B. If you are okay with showing the one off "sorry, we just ran out of stock" message. you should lock the item just before you bill (well, you could do that after transaction is complete. but at the cost of a very furious customer)
I would chose approach A for locking, and may be flag a "selling out soon" warning for items with very low stock left. (if its a very frequent situation, you could proly also count the number of concurrent users hitting on the item and give a more accurate warning)
From the business perspective, you wouldn't want to be so low on stock (lower than the number of concurrent buyers) This is inevitable of course at "christmas" times when its okay to be out of stock :)
This is a follow up from my last question: MySQL - Best method to saving and loading items
Anyways, I've looked at some other examples and sources, and most of them have the same method of saving items. Firstly, they delete all the rows that's already inserted into the database containing the character's reference, then they insert the new rows accordingly to the current items that the character has.
I just wanted to ask if this is a good way, and if it would cause a performance hit if i were to save 500 items per each character or so. If you have a better solution, please tell me!
Thanks in advance, AJ Ravindiran.
It would help if you talked about your game so we could get a better idea of your data requirements.
I'd say it depends. :)
Are the slot/bank updates happening constantly as the person plays, or just when the person savles their game and leaves. Also does the order of the slots really matter for the bank slots? Constantly deleting and inserting 500 records certainly can have a performance hit, but there may be a better way to do it, possibly you could just update the 500 records without deleting them. Possibly your first idea of 0=4151:54;1=995:5000;2=521:1;
wasn't SO bad. If the database is only being used for storing that information, and the game itself is managing that information once its loaded. But if you might want to use it for other things like "What players have item X", or "What is the total value of items in Player Ys bank". Then storing it like that won't allow you to ask the database, it would have to be computed by the game.
I've seen several question on how to secure and prevent abuse of ranking systems (like staring movies, products, etc) but nothing on actually implementing it. To simplify this question, security is not a concern to me, the people accessing this system are all trusted, and abuse of the ranking system if it were to happen is trivial and easier to revert than cause. Anyways, I'm curious how to store the votes.
One thought is to have a votes table, that logs each vote, and then either immediately, at scheduled times, or on every load of the product (this seems inefficient, but maybe not) the votes are tallied and a double between 0 and 5 is updated into the product's entry in the product table.
Alternatively, I store in the products table a total score and a number of votes, and just divide that out when I display, and add the vote to total and increment number when someone votes.
Or is there a better way to do it that I haven't though of? I'd kind of like to just have a 'rating' field in the product table, but can't think of a way to update votes without some additional data.
Again, data integrity is important, but by no means necessary, any thoughts?
I would keep a "score" with your products but would also keep a vote table to see who voted for what. And when somebody votes, Insert vote, update product score.
This allows quick sorting and you also have a table to be able to recalculate the scores from and to stop people double-voting.
There is no need to wait to write the vote and update the scores. That will introduce problems and if it's acting like a traditional system (lots more reads than writes), gives you no benefits.
you mean, you'll store the votes seperately in a table and then update the respective ranking of product in product's table with a defined strategy?
That seems like an inefficient way of storing it. Maybe there is a background to that reason; but why would you not want to store all votes in one table and keep making references of those votes to respective product. This gives you a real time count.
On UI you'll calculate a average of all the votings to a near integer to show. That would suffice, isn't it? Or am I missing something?
I agree with Oli. In addition, you can cache your score. So you update the product score in the cache and your application always picks up the cache value. Thus even on a page refresh, you would get the latest score without hitting the database.