So I'm using WampServer with the default phpMyAdmin to store this SQL table called Typing.
Table: Typing
Now I want to set the typing column to 0 for any row that has set the typing column to 1 more than five seconds ago.
For ex. I just set the typing column to 1 for the first row and my database detects the time since this 1 has been written, then it sets a 5 second timer to revert that 1 back to a 0. If 1 is overwritten with another 1 during that time, that timer should rest.
How should I go about this? Should I have a column for a 'timestamp' of each record? How do I make my database constantly check for entries older than 5 seconds without user input? Do I need an always on PHP script or a database trigger and how would I go about that?
As #JimL suggested, it might be a bit too ambitious to purge the records after only five seconds.
It might be helpful to have more information about what you're trying to accomplish, but I'll answer in a generic way that should answer your question
How I would handle this is that any queries should check for records that are less than five seconds old (I assume you're querying the data and only want records that are less than five seconds, otherwise I'm not really following the point of your question).
Once a day, or hourly if you have that much data, you can run a scheduled job (scheduled through MySQL itself, not through cron/Windows Scheduled Tasks) to purge the old records. You can use phpMyAdmin to set that up (the "Events" tab), although it's actually a MySQL feature that doesn't require phpMyAdmin.
I got it, I added a timestamp to each record and used this code:
mysqli_query($con,"DELETE FROM 'typing' WHERE TIMESTAMPDIFF(SECOND,recordDate, CURRENT_TIMESTAMP) > 1");
It's not a chron job though so it only runs if there is someone accessing the site, but it's good enough for what I need. Thanks for the help everyone :)
Related
I'm using a query that calculates some values on a table with about 11 millions rows. And I need to display the results in real time (on my site), but this calculations need about 1min to execute. The table content changes each 30 mins, so I don't have to recalc the results at each time user reloads the page. How can I cache the results of calculations? Via php (I use odbc) or using some sql statement, some sybase IQ option. Thanks.
I also asked this question at https://dba.stackexchange.com/. So sorry for duplicating, can't figure out where is the better place.
So I found the solution. Not optimized, but helpful for me. I insert my calculations into temp table, and add there a column with current date. On a script start I'm checking if table is older then 30mins, and if so, I drop it and crwate again.
In the website im working on i need to add user points. Every user will have it's own points and maximum amount of points will be 200. And upon registration user gets 100 points. With various tasks user points will be deducted.
But main problem im struggling is how to add points to the user, since every user need to gets 1 point every hour unless he have 200 or more points.
My first thought was to do a cronjob where it will run every hour a script which will check if user is verified and if user have less than 200 points and add 1 point to every user.
But after some reading im thinking of different approach which i don't understand quite exactly. The better approach, less server resource consuming would be to run a function which will check every time when user login how many points he have and add appropriate number of points to him. Problem is i don't know how to set it, how to calculate how many points to add to user if he was offline like 8 hours and how to time it? Or even maybe use ajax with timer?
What would be your suggestion and approach to this ?
Edit: Just to add since you ask, users doesn't see each other points.
When a user does something, check the last time you gave them points. If it was 5 hours ago, give them 5 points. If it was 10 hours ago, give them 10 points. Etc. Implement caching so if a user visits your site 50 times in one hour, you don't have to check against the DB every time.
Anyway, short answer is, do the check when loading the user data, rather than automatically every hour for all users whether they are active or not.
UPDATE users
SET points = MIN(points + 1, 200)
I don't really see the problem with this script running as a cron. Would be more problem if you handled each event as transaction points, since you'd have to run something like:
# Generates a row each hour per uncapped user, which may become a lot
INSERT INTO transcations (points, type, created)
SELECT 1, 'HOURLY_INCOME', NOW()
FROM users
WHERE points < 200
Is it relevant for other users, or official/inofficial statistics to check what their current point is? This is quite relevant, since it won't work fully if it only updates upon login.
user_table
---------------
id | reg_date
1 | 2013-10-10 21:10:15
2 | 2013-10-11 05:56:32
Just look how many hours left after user registration, add 100 points:
SELECT
TIMESTAMPDIFF(HOUR, `reg_date`, NOW())+100 AS `p`
FROM
user_table
WHERE
id = 1
And then check in PHP if result more than 200 just show 200.
Hmm, from mysql 5.1 there is neat feature which is basically mysql cron called MySQL Event Scheduler, and i think ill go with that for now since cron script will be very easy to write, small and not time consuming.
All i need to do is to write
UPDATE users SET points = (points +1) WHERE points<200
And add it to mysql event recurring every hour.
We have an internal PHP web app that's used for scheduling. We often have multiple users trying to schedule appointments for the same time slot, but we have a hard limit on how many appointments we can have per available time.
We've used PHP to verify that there are available slots before booking, but there's still enough time between PHP checking the table and the insert that overbooking can still happen.
I believe the solution is a MySQL trigger that checks the table before the insert. The problem is that I need MySQL to be able to count the number of records that have the same "schedule_id" and "schedule_user_date" as the record about to be inserted (this will be how many appointments already exist for that time slot).
I have to somehow let the trigger know what the maximum time slot is, which is where I'm stuck, since this can change from client to client.
If you have other suggestions other than a MySQL trigger, I'd like to hear about those as well.
I'm building an instant win action for a competition draw. Basically at a given randomly selected minute of an hour, the next user to submit their details should be chosen as the winner.
The problem I'm having is that if MySQL is running multiple connections, then how do I stop two or three winners being drawn by mistake? Can I limit the connections, or maybe get PHP to wait until all current MySQL connections are closed?
have a look at lock tables
http://dev.mysql.com/doc/refman/5.0/en/lock-tables.html
Use the starting value of a field that you're updating as the concurrency check in your WHERE clause when you make the update. That way, only the 1st one to be executed will go through, because after that it will no longer match the WHERE clause. You can tell whose went through using the mysql_affected_rows() function, which will return 1 for the successful update and 0 for any others.
Use a timestamp field "registertime" in the user details table. When inserting the data, use the NOW() function to insert into the registertime field.
When you choose a random minute, convert that to a unix time.
The winner is: SELECT * FROM userTable WHERE registertime > -- the timestamp of your random minute -- ORDER BY registertime LIMIT 1
Keep a small status table somewhere that records the hour of the previous draw. If the new record's insert time is at a different hour, do the check if they're a winner.
If they are, you update the status table with this new "Winners" draw hour, and that'll prevent any more draws being made for the rest of the hour. Though, what happens if, by chance, no one actually "wins" the draw in any particular hour? Do you guarantee a win to the last person who registered, or there just isn't a winner at all?
Which method do you suggest and why?
Creating a summary table and . . .
1) Updating the table as the action occurs in real time.
2) Running group by queries every 15 minutes to update the summary table.
3) Something else?
The data must be near real time, it can't wait an hour, a day, etc.
I think there is a 3rd option, which might allow you to manage your CPU resources a little better. How about writing a separate process that periodically updates the summarized data tables? Rather than recreating the summary with a group by, which is GUARANTEED to run slower over time because there will be more rows every time you do it, maybe you can just update the values. Depending on the nature of the data, it may be impossible, but if it is so important that it can't wait and has to be near-real-time, then I think you can afford the time to tweak the schema and allow the process to update it without having to read every row in the source tables.
For example, say your data is just login_data (cols username, login_timestamp, logout_timestamp). Your summary could be login_summary (cols username, count). Once every 15 mins you could truncate the login_summary table, and then insert using select username, count(*) kind of code. But then you'd have to rescan the entire table each time. To speed things up, you could change the summary table to have a last_update column. Then every 15 mins you'd just do an update for every record newer than the last_update record for that user. More complicated of course, but it has some benefits: 1) You only update the rows that changed, and 2) You only read the new rows.
And if 15 minutes turned out to be too old for your users, you could adjust it to run every 10 mins. That would have some impact on CPU of course, but not as much as redoing the entire summary every 15 mins.