Как сохранить дату рождения и возраст, чтобы можно было ежедневно обновлять возраст в PHP/MySQL?

Как я должен хранить Birthdate's в MySQL, чтобы я мог легко обновлять возраст каждого на ежедневной основе с помощью Cron Job?

Имеет ли смысл даже хранить возраст и дату рождения, чтобы при выполнении поиска с использованием возраста мне не приходилось вычислять каждый возраст на лету и тратить ресурсы ЦП?

Если да, то как мне 1) хранить дату рождения и 2) вычислять возраст каждый день?

Я могу себе представить, что ежедневный скрипт cron сначала отфильтровывает пользователя, чей месяц рождения не является текущим месяцем, затем отфильтровывает пользователя, чей день рождения не является текущим днем, а затем увеличивает на единицу возраст каждого оставшегося пользователя.

Имеет ли это смысл? Если так, как бы я это сделал? Есть ли лучший способ сделать все это?

5 ответов

Решение

Простой ответ - нет; никогда не храните возраст людей. Он меняется для каждого человека в год, но, как вы говорите, вы должны ежедневно проверять, правильно ли это для каждого человека.

Сохраните только дату рождения, а затем рассчитывайте возраст при выборе из базы данных. Это только today - date of birth так что почти не занимает процессоров вообще.

РЕДАКТИРОВАТЬ:

В продолжение моего комментария в ответе ManseUK также есть вероятность провала. Что произойдет, если ваш сервер / база данных не работает? Или ваше обновление не запускается в указанное время? Или кто-то приходит и запускает его вручную после того, как обновление уже запущено на эту дату? Или кто-то выключает ваш планировщик? Там нет никакой опасности этого произойдет, если вы рассчитываете Age как вы выбираете из базы данных.

Чтобы выбрать возраст от 25 до 30 лет с учетом столбца ДАТА dateofbirth Ваш запрос будет выглядеть примерно так:

select *
  from users
 where dateofbirth between date_add( curdate(), interval -30 year )
                       and date_add( curdate(), interval -25 year )

обеспечивать users индексируется на dateofbirth,

Нет, не храните возраст, просто рассчитайте его в своих запросах. Что касается дня рождения, я предпочитаю, чтобы все мои дата / время были в метках времени Unix (потому что я ненавижу иметь дело с переносимостью через настройки локали, изменяющие формат даты)

Имеет ли смысл хранить Age

Нет.

Мне не нужно рассчитывать каждый возраст на лету и тратить ресурсы процессора?

На самом деле, вы бы потратили еще миллион "ресурсов ЦП" (о которых у вас слишком смутное представление, чтобы о них беспокоиться) при ежедневном обновлении.

Есть ли лучший способ сделать все это?

Сохраните дату рождения и рассчитайте возраст в выбранное время

что если вы хотите узнать всех тех, чей возраст больше 25, но меньше 30?

это довольно тривиальный запрос, как этот

WHERE birth_date BETWEEN date_sub(curdate(), INTERVAL 25 YEAR) 
                     AND date_sub(curdate(), INTERVAL 30 YEAR)

запрос будет использовать индекс (если таковой имеется) и, следовательно, будет быстрым, без каких-либо [ненужных] денормализаций

Я собираюсь пойти против большинства всех ответов здесь.

Я бы сохранил оба...

  • Обновление возраста происходит быстро и просто - один запрос mysql может выполняться каждый день, и его выполнение
  • вычисление возраста занимает много времени, если у вас много просмотров страниц - количество просмотров значительно превышает количество изменений

Просто представьте себе сценарий таблицы - таблицу с 100 или 1000 строками, которая показывает возраст человека... сколько времени это займет для вычисления???

Я всегда думал, что Stackru вычисляет репутацию динамически, но вы можете увидеть в проводнике данных Stackru, что они этого не делают - см. Объект User в схеме справа. Он записывается и обновляется каждый раз, когда его изменяют - я полагаю, что это только из-за того, что количество просмотров значительно превышает количество изменений.

Я не думаю, что это правда, что компьютерный век динамически отнимает много памяти. Почему бы не создать таблицу КАЛЕНДАРЬ с 365 строками по 1 строке на каждый день года. И сохраните список идентификаторов пользователей против дня, соответствующего их дню рождения. Для каждого дня просто обратитесь к записи таблицы для этого дня и обновите возраст только тех выбранных пользователей. Это значительно уменьшит сложность, даже когда пользовательская база увеличится.

Другие вопросы по тегам