How to store age in SQL using PHP [duplicate] - php

How should I store Birthdate's in MySQL so that I can easily update everyone's Age on a daily basis via a Cron Job?
Does it even make sense to store the Age AND the Birthdate so that when searches involving the Age are made, I don't have to calculate each Age on-the-fly and waste CPU resources?
If so, how should I 1) store the Birthdate, and 2) calculate the Age each day?
I can imagine the daily cron script first filtering out the user's whose Birthdate month is not the current month, then filtering out the user's whose Birthdate day is not the current day, and then incrementing by one the age of each user that is left.
Does this make sense? If so, how would I do that? Is there a better way to do all of this?

The simple answer is don't; never store a persons age. It changes for each person yearly but, as you say, you have to check that it's correct for every person daily.
Only store the date of birth, and then calculate the age when selecting from the database. It's only today - date of birth so takes almost no CPUs at all.
EDIT:
To expand upon my comment in ManseUK's answer there's also the possibility of failure. What happens if your server / database is down? Or your update fails to run at its specified time? Or someone comes along and runs it manually after the update already been run for that date? Or someone turns off your scheduler? There's no danger of this happening if you calculate Age as you select from the database.
To select where age is between 25 and 30 years and assuming a DATE column dateofbirth your query would be something like:
select *
from users
where dateofbirth between date_add( curdate(), interval -30 year )
and date_add( curdate(), interval -25 year )
Ensure users is indexed on dateofbirth.

No, don't store age, just calculate it in your queries. As for the birthday, I prefer to have all my date/time in unix timestamps (because I hate to deal with portability across date-format-changing locale settings)

Does it even make sense to store the Age
No.
I don't have to calculate each Age on-the-fly and waste CPU resources?
As a matter of fact, you'd waste a zillion more "CPU resources" (of which you have too vague idea to be concerned of) with your everyday update approach.
Is there a better way to do all of this?
Store the birthdate and calculate the age at select time
what if you want to find out all the ones whose Age is greater than 25 but less than 30?
this is quite trivial query like this
WHERE birth_date BETWEEN date_sub(curdate(), INTERVAL 25 YEAR)
AND date_sub(curdate(), INTERVAL 30 YEAR)
the query would using an index (if any) and thus be blazing fast, without any [unnecessary] denormalizations

Im going to go against the majority all of the answers here.
I would store both ...
updating the age is quick and simple - a single mysql query could run every day and its done
calculating the age is time consuming when you have lots of page views - amount of times its viewed far outweighs the number of changes
Just imagine a table scenario - a table with 100 or 1000 rows that shows the age of a person ... how long is that going to take to compute ???
I always thought that Stackoverflow calculated the Reputation dynamically but you can see on the Stackoverflow data explorer that they dont - see the User object in the schema on the right. Its recorded and updated each time its changed - I would guess that this is purely because of the amount of times its viewed far outweighs the number of changes

I don't think it's totally true that computing age dynamically takes a lot of memory.
Why not create a table CALENDAR with 365 rows 1 row for each day of an year. And store a list of userid against the day corresponding to their birthday.
For each day just refer the table entry for that day and refresh the age of only those selected users.
This will reduce the complexity greatly even when the user base increases.

Related

Update age column in database using php mysqli or pdo

How to update age automatically based on its DOB? I'm planning to write a script that fetch DOB column then calculate the age and update it. I started my idea but it still doesn't meet my objective.
Pls. help! Thanks in advance :)
Adding an age column when you have already date of birth, is slightly futile. Also, this means you would need to update the value once a year for every record, and at their birth date. That will start to get heavier and heavier. A lot of comments suggested to do the calculation of the age in PHP, this also would get heavy if you wanted to group people by age, you'd have to grab every records of the database and calculate their age. My suggestion is to use MySQL to calculate it, so you can use it in joins, where clauses, group bys and so on...
SELECT YEAR(NOW()) - YEAR(birthdate) - (DATE_FORMAT(NOW(), '%m%d') < DATE_FORMAT(birthdate, '%m%d')) as age FROM table
For more details, this was taken from How to get the difference in years from two different dates? which accounts for leap years.
You could easily create a MySQL function, call it calc_age or something and pass it the birthdate, that would return the current age and would be very easy to use...

Building a scheduler with sql, php. Most efficient way

I am creating a system that requires a schedular for a particular task. Users may pick from times 24 hours a day, 7 days a week.
I came up with a few options for the database storage, but I don't think either one is the most efficient design, so I'm hoping for some possible alternatives that may be more efficient.
On the user side I created a grid of buttons with 2 loops to create the days, and the times, and I set each a unique value of $timeValue = "d".$j."-t".$i;
So d1-t0 will be Saturday at Midnight d3-t12= Tuesday at Noon, and so forth.
So, in the database I was first going to simply have a ID, day, time set up, but that would result in a possible 168 rows per event
Then I tried an ID, day, and time 0-23 (a column for each hour of the day) And I was simply going to have a boolean set up. 0 if not selected, 1 if it is.
This would result in 7 rows per event, but I think querying that data might be a pain.
I need to perform a few functions on this data. On each day, list the number of selected times into an array. But I don't believe having a select statement of SELECT * from schedule where time0, =1 or time1= 1 .... ect will work, nor will it produce the desired array. (times=(0,3,5,6,7...)
So, this isnt going to work well.
My overall system will need to also know every event that has each time selected for a mass posting.
"Select * from table where time = $time (0-23) and day= $day (1-7)
Do action with data...
So with this requirement, I'm going to assume that storing the times as an array within the database is likely not the most efficient way either.
So am I stuck with needing up to 168 rows of data per event, or is there a better way I am missing? Thanks
Update:
To give a little more clarity on what I need to accomplish:
Users will be creating event campaigns in which other users can bid on various time slots for something to happen. There will likely be 10-100 thousand of these campaigns at any one time and they are ongoing until the creator stops them. The campaign creators can define the time slots available for their campaign.
At the designated time each day the system will find every campaign that has an event scheduled and perform the event.
So the first requirement is to know which time slots are available for the campaign, and then I need the system to quickly identify campaigns that have an event on each hour and day and perform it automatically.

How to store Birthdate and Age so that Age can be updated daily in PHP/MySQL?

How should I store Birthdate's in MySQL so that I can easily update everyone's Age on a daily basis via a Cron Job?
Does it even make sense to store the Age AND the Birthdate so that when searches involving the Age are made, I don't have to calculate each Age on-the-fly and waste CPU resources?
If so, how should I 1) store the Birthdate, and 2) calculate the Age each day?
I can imagine the daily cron script first filtering out the user's whose Birthdate month is not the current month, then filtering out the user's whose Birthdate day is not the current day, and then incrementing by one the age of each user that is left.
Does this make sense? If so, how would I do that? Is there a better way to do all of this?
The simple answer is don't; never store a persons age. It changes for each person yearly but, as you say, you have to check that it's correct for every person daily.
Only store the date of birth, and then calculate the age when selecting from the database. It's only today - date of birth so takes almost no CPUs at all.
EDIT:
To expand upon my comment in ManseUK's answer there's also the possibility of failure. What happens if your server / database is down? Or your update fails to run at its specified time? Or someone comes along and runs it manually after the update already been run for that date? Or someone turns off your scheduler? There's no danger of this happening if you calculate Age as you select from the database.
To select where age is between 25 and 30 years and assuming a DATE column dateofbirth your query would be something like:
select *
from users
where dateofbirth between date_add( curdate(), interval -30 year )
and date_add( curdate(), interval -25 year )
Ensure users is indexed on dateofbirth.
No, don't store age, just calculate it in your queries. As for the birthday, I prefer to have all my date/time in unix timestamps (because I hate to deal with portability across date-format-changing locale settings)
Does it even make sense to store the Age
No.
I don't have to calculate each Age on-the-fly and waste CPU resources?
As a matter of fact, you'd waste a zillion more "CPU resources" (of which you have too vague idea to be concerned of) with your everyday update approach.
Is there a better way to do all of this?
Store the birthdate and calculate the age at select time
what if you want to find out all the ones whose Age is greater than 25 but less than 30?
this is quite trivial query like this
WHERE birth_date BETWEEN date_sub(curdate(), INTERVAL 25 YEAR)
AND date_sub(curdate(), INTERVAL 30 YEAR)
the query would using an index (if any) and thus be blazing fast, without any [unnecessary] denormalizations
Im going to go against the majority all of the answers here.
I would store both ...
updating the age is quick and simple - a single mysql query could run every day and its done
calculating the age is time consuming when you have lots of page views - amount of times its viewed far outweighs the number of changes
Just imagine a table scenario - a table with 100 or 1000 rows that shows the age of a person ... how long is that going to take to compute ???
I always thought that Stackoverflow calculated the Reputation dynamically but you can see on the Stackoverflow data explorer that they dont - see the User object in the schema on the right. Its recorded and updated each time its changed - I would guess that this is purely because of the amount of times its viewed far outweighs the number of changes
I don't think it's totally true that computing age dynamically takes a lot of memory.
Why not create a table CALENDAR with 365 rows 1 row for each day of an year. And store a list of userid against the day corresponding to their birthday.
For each day just refer the table entry for that day and refresh the age of only those selected users.
This will reduce the complexity greatly even when the user base increases.

Can I auto-publish articles with future timestamp?

Is there a way to add articles (data) in mysql/php but make them
auto-publish during the day when I´m not available.
So lets say, if I have a news site but I´ll be busy tomorrow the whole day so I could pre-write articles the day before with timestamp and they would appear when I want
Is this possible?
How would the script be like:
SELECT FROM articles WHEN TIME is 2011-12-01 12:15
Thanks
As simple as:
SELECT * FROM articles WHERE timestamp <= NOW()
Though I never worked with them to me the easiest solutions seems to be Cronjobs combined with an extra waiting table and a script linking both.
You pre-write your article and store them in table together with the time stamp you want to publish them.
Your cron will invoke a script every 2,3, 5 hours (twice a day, whatever).
This script checks the time stamps in the table against the actual time and if it is about time to realise the article it will do so (or hand the information to the realise script).

MYSQL Optimzation: Fetching Data w.r.t DAY OF THE WEEK

I have to work on CRON which will be sending email to subscriber weekly on the day they get subscribed. For example if user A subscribed on Thursday and user B subscribed on Wednesday then user A will get mail on every Thursday and user B on every Wednesday.
Now my approach will be following:
1- First get the day of the week of current(TODAY) date and assign in a variable
2- Running the SELECT query and fetch all subscriber IDs who's subscription day's is similar to the day of Today's Date. I am planning to use MYSQL's dayofweek() to extract day from Week,
3- Once getting all IDs then send last 7 day activities to those subscribers via email.
Thing thing which is making me a bit puzzled is DAYOFWEEK() function which column based and looks costly. What alternative would you suggest?(Assuming the table would have lots of data)
Per-row functions rarely scale well as the database table grows.
The first thing you should do is make sure there's actually a performance problem to solve. Always start with third normal form and regress only if you find such a problem, otherwise your effort is wasted. It may be that the speed is not that bad in which case stick with 3NF.
If it turns out there is a performance problem, one way to solve it is to add and indexed column called weekday that will hold the day of the week the user subscribed.
This is technically breaking 3NF since that attribute is dependent on the date of subscription which is unlikely to be part of the key. It may also come to disagree with that subscription date if you update one or the other independently.
But you can mitigate the problem by having an insert/update trigger which forces the weekday column to agree with the subscription date, ensuring that they never disagree.
Then your query simply becomes something like:
dow = Now.dayOfWeek()
rowSet = executeQuery ("select sub_id from subscribers where weekday = ?", dow)
and then processing each of those subscribers (or as one big honkin' query if you wish).
The fact that you're not having to retrieve every row to do a getWeekDay (subscription_date) and filter the rows should massively improve the query speed.
The vast majority of databases are read far more often than written and, by shifting the cost of the calculation to the insert/update, you effectively amortise that cost over all selects.
Assuming your subscribers subscribe for more than a week (since you send out their stuff once a week), that will be more efficient than calculating on the select.
And, although this takes up more space in your table (due to the extra column and index), have a look at the ratio of "My query isn't fast enough" questions compared to "My database is too big" questions. The former far outweigh the latter.

Categories