Я хочу хранить время в таблице базы данных, но нужно хранить часы и минуты. Я знаю, что могу просто использовать DATETIME и игнорировать другие компоненты даты, но как лучший способ сделать это, не сохраняя больше информации, чем мне действительно нужно?
Лучший способ хранения времени (чч: мм) в базе данных
Ответ 1
Вы можете сохранить его как целое число за последние полчаса:
например.
0 = 00:00
60 = 01:00
252 = 04:12
Однако вам нужно будет написать код для восстановления времени, но это не должно быть сложно.
Ответ 2
Если вы используете SQL Server 2008+, рассмотрите тип данных TIME
. статья SQLTeam с большим количеством примеров использования.
Ответ 3
Просто сохраняйте регулярное время и игнорируйте все остальное. Зачем тратить лишний код времени на загрузку, который загружает int, манипулирует им и преобразует его в datetime, когда вы можете просто загрузить дату-время?
Ответ 4
DATETIME start DATETIME end
Я прошу вас использовать два значения DATETIME, помеченные как event_start и event_end.
Время - сложный бизнес
В большинстве стран мира для большинства измерений правильна или ошибочно принята метрическая система, основанная на отрицании. Это хорошо в целом, потому что по крайней мере мы все можем согласиться с тем, что g, является ml, является кубическим см. По крайней мере, примерно так. Метрическая система имеет много недостатков, но по крайней мере она на международном уровне последовательно испорчена.
Однако со временем мы имеем; 1000 миллисекунд в секунду, от 60 секунд до минуты, от 60 минут до часа, 12 часов на каждые полдня, приблизительно 30 дней в месяц, которые варьируются в зависимости от месяца и даже года, о котором идет речь, каждая страна имеет свое временное смещение от других, время, отформатированное в каждой стране, меняется.
Это много, чтобы переварить, но для этого сложного сценария не может быть сложного и длинного.
Некоторые углы можно разрезать, но есть те, где разумнее не
Хотя главный ответ здесь говорит о том, что вы храните целое число минут за полночь, может показаться совершенно разумным, я научился избегать трудностей.
Причины внедрения двух значений DATETIME - это увеличение точности, разрешения и обратной связи.
Все это очень удобно, когда дизайн создает нежелательные результаты.
Я храню больше данных, чем требуется?
Вначале это может показаться, что больше информации хранится, чем я требую, но есть веская причина для этого.
Хранение этой дополнительной информации почти всегда заканчивается тем, что экономит время и силы в долгосрочной перспективе, потому что я неизбежно нахожу, что, когда кому-то говорят, сколько времени нужно, они дополнительно захотят узнать, когда и где произошло событие тоже.
Это огромная планета
В прошлом я был виноват в игнорировании того, что есть другие страны на этой планете, кроме моих собственных. В то время это казалось хорошей идеей, но это ВСЕГДА приводило к проблемам, головным болям и потерянному времени позже. ВСЕГДА учитывайте все часовые пояса.
С#
DateTime отлично отображает строку в С#. Метод ToString (строковый формат) компактен и легко читается.
например.
new TimeSpan(EventStart.Ticks - EventEnd.Ticks).ToString("h'h 'm'm 's's'")
Сервер SQL
Кроме того, если вы читаете свою базу данных отдельно для вашего интерфейса приложения, то dateTimes приветствуются, чтобы читать с первого взгляда, и выполнять вычисления на них просты.
например.
SELECT DATEDIFF(MINUTE, event_start, event_end)
Стандарт даты ISO8601
Если вы используете SQLite, тогда у вас этого нет, поэтому вместо этого используйте текстовое поле и сохраните его в формате ISO8601, например.
"2013-01-27T12: 30: 00 + 0000"
Примечания:
-
В этом случае используется 24-часовой режим *
-
+0000 часть ISO8601 отображает непосредственно на решетку в координаторе GPS. Поэтому стоит подумать, стоит ли хранить долготу, мощность и высоту вместе с данными. Это будет зависеть от приложения.
-
ISO8601 - международный формат.
-
Вики очень полезны для дальнейших подробностей в http://en.wikipedia.org/wiki/ISO_8601.
-
Дата и время сохраняются в международном времени, и смещение записывается в зависимости от того, где в мире было сохранено время.
По моему опыту всегда нужно хранить полную дату и время, независимо от того, думаю ли я, когда начинаю проект. ISO8601 - очень хороший, надежный способ сделать это.
Дополнительные советы бесплатно
Также стоит группировать события вместе как цепочку. Например. если вы записываете гонку, все событие может быть сгруппировано гонщиком, race_circuit, circuit_checkpoints и circuit_laps.
По моему опыту, также разумно определить, кто сохранил запись. Либо как отдельная таблица, заполненная триггером, либо как дополнительный столбец в исходной таблице.
Чем больше вы входите, тем больше вы выходите
Я полностью понимаю стремление быть максимально экономичным с пространством, но я редко делал это за счет потери информации.
Правило большого пальца с базами данных, как гласит название, база данных может только сказать вам столько, сколько у нее есть данные, и может быть очень дорого вернуться к историческим данным, заполнив пробелы.
Решение заключается в том, чтобы получить его правильно в первый раз. Это, конечно же, легче сказать, чем сделать, но теперь вы должны иметь более глубокое понимание эффективного дизайна базы данных и впоследствии значительно повысить вероятность его правильного в первый раз.
Чем лучше ваш первоначальный дизайн, тем менее дорогостоящий ремонт будет позже.
Я только говорю все это, потому что, если я смогу вернуться вовремя, то это то, что я сказал бы себе, когда я туда доберусь.
Ответ 5
так как вы не отметили его бит, если вы находитесь на SQL Server 2008, вы можете использовать тип данных времени, иначе используйте минуты с полуночи.
Ответ 6
Я бы преобразовал их в целое число (HH * 3600 + MM * 60) и сохранил его таким образом. Небольшой размер хранилища и все еще достаточно легкий для работы.
Ответ 7
Если вы используете MySQL, используйте тип поля TIME и связанные с ним функции, которые поставляются с TIME.
00:00:00 - стандартный формат времени unix.
Если вам когда-либо приходилось оглядываться назад и просматривать таблицы вручную, целые числа могут быть более запутанными, чем фактическая отметка времени.
Ответ 8
SQL Server фактически хранит время как доли дня. Например, 1 целый день = значение 1,12 часа - это значение 0,5.
Если вы хотите сохранить значение времени без использования типа DATETIME, сохранение времени в десятичной форме соответствовало бы этой потребности, а также упрощало бы преобразование в DATETIME.
Например:
SELECT CAST(0.5 AS DATETIME)
--1900-01-01 12:00:00.000
Сохранение значения как DECIMAL (9,9) потребует 5 байтов. Однако, если точность не имеет особого значения, REAL будет потреблять всего 4 байта. В любом случае совокупный расчет (т.е. Среднее время) можно легко вычислить по числовым значениям, но не по типам данных/времени.
Ответ 9
Попробуйте smalldatetime. Это может не дать вам то, что вы хотите, но оно поможет вам в ваших будущих потребностях в манипуляциях даты/времени.
Ответ 10
Вы уверены, что вам понадобятся часы и минуты? Если вы хотите сделать что-нибудь значимое (например, рассчитать промежутки времени между двумя такими точками данных), не имея информации о часовых поясах, а DST может давать неверные результаты. Часовые пояса, возможно, не применяются в вашем случае, но DST, безусловно, будет.
Ответ 11
Я думаю, что вы запрашиваете переменную, которая будет хранить минуты в виде числа. Это можно сделать с помощью различных типов целочисленной переменной:
SELECT 9823754987598 AS MinutesInput
Затем в вашей программе вы можете просто просмотреть это в форме, которую вы хотели бы вычислить:
long MinutesInAnHour = 60;
long MinutesInADay = MinutesInAnHour * 24;
long MinutesInAWeek = MinutesInADay * 7;
long MinutesCalc = long.Parse(rdr["MinutesInput"].toString()); //BigInt converts to long. rdr is an SqlDataReader.
long Weeks = MinutesCalc / MinutesInAWeek;
MinutesCalc -= Weeks * MinutesInAWeek;
long Days = MinutesCalc / MinutesInADay;
MinutesCalc -= Days * MinutesInADay;
long Hours = MinutesCalc / MinutesInAnHour;
MinutesCalc -= Hours * MinutesInAnHour;
long Minutes = MinutesCalc;
Возникает проблема, когда вы запрашиваете эффективность, которая будет использоваться. Но, если вам не хватает времени, тогда просто используйте значение nullable BigInt для хранения вашего значения минут.
Значение null означает, что время еще не записано.
Теперь я объясню в форме кругового путешествия в космос.
К сожалению, столбец таблицы будет хранить только один тип. Поэтому вам нужно будет создать новую таблицу для каждого типа, как требуется.
Например:
-
Если MinutesInput = 0.. 255, используйте TinyInt (конвертировать, как описано выше).
-
Если MinutesInput = 256.. 131071, используйте SmallInt (Примечание: SmallInt min значение -32,768. Поэтому отрицайте и добавляйте 32768 при хранении и извлечение значения для использования полного диапазона перед преобразованием, как указано выше).
-
Если MinutesInput = 131072.. 8589934591, используйте Int (Примечание: Отмените и добавьте 2147483648 при необходимости).
-
Если MinutesInput = 8589934592.. 36893488147419103231, используйте BigInt (Примечание: добавьте и отрицайте 9223372036854775808, если необходимо).
-
Если MinutesInput > 36893488147419103231, то я лично использовал бы VARCHAR (X) увеличивает X по мере необходимости, так как a char является байтом. мне нужно придется пересмотреть этот ответ позднее, чтобы полностью описать это (или, может быть, сотрудник stackoverflowee может завершить этот ответ).
Поскольку каждому значению, несомненно, потребуется уникальный ключ, эффективность базы данных будет очевидна только в том случае, если диапазон сохраненных значений является хорошим сочетанием между очень маленькими (близкими к 0 минутам) и очень высокими (более 8589934591),
До тех пор, пока значения, хранящиеся на самом деле, не достигнут числа, превышающего 36893488147419103231, тогда у вас может быть один столбец BigInt для представления ваших минут, так как вам не нужно тратить Int на уникальный идентификатор и другой int для хранения минут.
Ответ 12
Вместо минут за полночь мы храним его как часы в 24 часа, как SMALLINT.
09:12 = 912 14:15 = 1415
при обращении к "удобочитаемой форме" мы просто вставляем двоеточие ":" два символа справа. Левая панель с нулями, если вам нужно. Сохраняет математику каждый путь и использует несколько меньших байтов (по сравнению с varchar), плюс обеспечивает, чтобы значение было числовым (а не буквенно-цифровым)
Довольно тупой, хотя... должен существовать тип данных TIME в MS SQL уже много лет IMHO...
Ответ 13
Экономия времени в формате UTC может помочь лучше, как предложила Кристен.
Убедитесь, что вы используете 24-часовой такт, потому что в UTC не используется меридиан AM или PM.
Пример:
- 4:12 AM - 0412
- 10:12 AM - 1012
- 14:28 - 1428
- 11:56 PM - 2356
Он по-прежнему предпочитает использовать стандартный четырехзначный формат.
Ответ 14
Сохраните ticks
как long
/bigint
, которые в настоящее время измеряются в миллисекундах. Обновленное значение можно найти, посмотрев на значение TimeSpan.TicksPerSecond
.
В большинстве баз данных есть тип DateTime, который автоматически сохраняет время как тики за кулисами, но в случае некоторых баз данных, например. SqlLite, сохранение тиков может быть способом хранения даты.
Большинство языков позволяют легко преобразовать из ticks
→ TimeSpan
→ ticks
.
Пример
В С# код будет выглядеть следующим образом:
long TimeAsTicks = TimeAsTimeSpan.Ticks;
TimeAsTimeSpan = TimeSpan.FromTicks(TimeAsTicks);
Помните, хотя, поскольку в случае SqlLite, который предлагает только небольшое количество различных типов; INT
, REAL
и VARCHAR
Необходимо будет сохранить количество тиков в виде строки или двух INT
ячеек в сочетании. Это потому, что INT
- это 32-битное число, а bigint
- 64-битное число.
Примечание
Мои личные предпочтения, однако, состоят в том, чтобы хранить дату и время как строку ISO8601
.
Ответ 15
ИМХО, какое лучшее решение зависит от некоторой степени от того, как вы храните время в остальной части базы данных (и остальной части вашего приложения)
Лично я работал с SQLite и стараюсь всегда использовать unix timestamps для хранения абсолютного времени, поэтому при работе со временем дня ( как вы просите) Я делаю то, что Глен Солсберри пишет в своем ответе и хранит количество секунд с полуночи.
При использовании этого общего подхода люди (включая меня!), читающие код, менее сбиты с толку, если я использую один и тот же стандарт везде