Как инженер-программист я часто сталкиваюсь с проблемами, связанными с балансом между скоростью, точностью и стоимостью. Одной из вечных проблем в моем развитии является учет времени — часто потому, что традиционные методы измерения времени слишком велики/громоздки или слишком точны для некоторых моих потребностей. Иногда я просто хочу сохранить некоторую действительно элементарную информацию о времени, которая полезна, но не требует высокой точности или оправдывает наличие всех тех битов, которые занимают данные.

Я собираюсь подойти и обсудить это с точки зрения базы данных, поскольку это особая проблема, которую я пытаюсь преодолеть прямо сейчас. Полные поля DATETIME чертовски точны, ориентированы на будущее и очень стабильны, но они также довольно раздуты, занимают 8 байт памяти и требуют немало математических вычислений для обработки. Временные метки Unix — разумный компромисс, если вы не слишком беспокоитесь о будущем, поскольку они вдвое меньше, занимают всего 4 байта памяти и их гораздо проще обрабатывать. Но я действительно хочу продвинуться дальше, что я могу получить всего в 2 байтах памяти для временной метки и могу ли я сделать это перспективным?!

Введите мое двухбайтовое решение для временных меток с низкой степенью детализации: краткосрочное время. Вот как это работает: 7 лет * 377 дней * 24 часа = 61 656. Мы можем хранить данные за 7 лет, до 377 дней в году (включая високосные и длинные високосные годы) и 24 часа в день в одном 2-байтовом беззнаковом целом.

Но почему детализация только по часам, разве это не ограничение?

Абсолютно точно, это узкое место. Но есть все виды временных меток, которые мы хотели бы хранить для целей сбора метрик, и вплоть до точной минуты и секунды не очень полезны, когда мы создаем большие отчеты и долгосрочные прогнозы. Вплоть до дня и часа подходит для многих потребностей сбора метрик. Кроме того, часто, когда мы ХРАНИМ метрики в базе данных, таблица представляет собой просто идентификатор пользователя (4 байта) и то, что они просматривали (4 байта), в сочетании с ДАТАВРЕМЯ (8 байтов), которые они просматривали. Боже мой, временная метка занимает ПОЛОВИНУ хранилища и даже не является самой важной точкой записи! С помощью поля «Кратковременное время» вы снижаете нагрузку на диск и в памяти до 2 байтов данных на запись — в таблице с 1 миллионом записей вы сокращаете примерно 16 МБ использования памяти/диска до всего 10 МБ — экономия 37,5%! Это довольно хорошее сжатие данных, когда вам не нужны ультратонкие временные метки.

Подождите, значит, я могу хранить информацию только за 7 лет?

Да, это самая ужасная часть. Что делает его еще более уродливым, так это то, что через 7 лет вам нужно начать «прокручивать» даты, когда год переворачивается в вашей базе данных. Это обратная сторона и стоимость всего этого сжатия. Таким образом, вам нужно сжать все ваши записи за 7-й год в какую-то другую историческую систему (если это необходимо для вашей истории), затем удалить все записи за 7-й год и увеличить оставшиеся записи на год (добавляя 9048 к каждой короткой системе). -Term поле Time в вашей базе данных). Разумеется, это требует ежегодных затрат и является частью стоимости использования этого формата. Но это делает проверку на будущее довольно простой, поскольку отсчет года идет назад от текущего года, а не на фиксированный момент времени в качестве его основы. Если данные через 7 лет довольно быстро выбрасываются, как в случае с моим необходимым использованием, то вы можете просто удалить все данные за 7-й год и свернуть то, что осталось.

А как насчет часовых поясов, времени пользователя и так далее?

Эта схема должна быть реализована в рамках локального времени базы данных, что в настоящее время уже является ограничением для многих РСУБД, или, по крайней мере, обычно так к ней относятся, поскольку часовые пояса и время пользователя чаще всего лучше вычисляются на стороне клиента, а не по базе данных. Стандартной и лучшей практикой для базы данных является использование собственного времени в качестве основного времени записи, и это удобно, поскольку ведет к единому источнику достоверности.

Это последовательно, можно ли сортировать по полю?

Безусловно, оно просто представлено в базе данных как беззнаковое целочисленное поле, и время отсчитывается от 7 лет назад, а затем вверх по дням года и часам дня. Таким образом, значение 0 (ноль) будет 1 января, в час полуночи, 7 лет назад.