Я хочу хранить время в таблице базы данных, но мне нужно хранить только часы и минуты. Я знаю, что могу просто использовать DATETIME и игнорировать другие компоненты даты, но как лучше всего сделать это, не сохраняя больше информации, чем мне действительно нужно?
sql-server
database
database-design
datetime
Мэтью Дрессер
источник
источник
Ответы:
Вы можете сохранить его как целое число минут после полуночи:
например.
Однако вам нужно будет написать код, чтобы восстановить время, но это не должно быть сложно.
источник
Если вы используете SQL Server 2008+, учитывайте
TIME
тип данных. Статья SQLTeam с дополнительными примерами использования.источник
Я умоляю вас использовать вместо этого два значения DATETIME , обозначенные чем-то вроде event_start и event_end .
Время - сложный бизнес
В настоящее время большая часть мира правильно или ошибочно приняла метрическую систему на основе Денери для большинства измерений. В целом это хорошо, потому что, по крайней мере, мы все можем согласиться с тем, что ag, это мл, это кубический см. По крайней мере, примерно так. Метрическая система имеет много недостатков, но, по крайней мере, она неизменно ошибочна на международном уровне.
Однако со временем у нас есть; 1000 миллисекунд в секунду, от 60 секунд до минуты, от 60 минут до часа, 12 часов на каждые полдня, примерно 30 дней в месяц, которые варьируются в зависимости от месяца и даже года, в каждой стране есть свое временное смещение относительно других , формат времени зависит от страны.
Это сложно переварить, но в целом для такого сложного сценария невозможно найти простое решение.
Некоторые углы можно обрезать, но есть такие, где разумнее не
Хотя главный ответ здесь предполагает, что вы храните целое число минут после полуночи, это может показаться вполне разумным, я научился избегать этого на горьком опыте.
Причины для реализации двух значений DATETIME заключаются в повышении точности, разрешения и обратной связи.
Все это очень удобно, когда дизайн дает нежелательные результаты.
Я храню больше данных, чем требуется?
Сначала может показаться, что хранится больше информации, чем мне нужно, но есть веская причина принять этот удар.
Хранение этой дополнительной информации почти всегда в конечном итоге экономит мне время и силы, потому что я неизбежно обнаруживаю, что, когда кому-то говорят, сколько времени что-то заняло, они также захотят узнать, когда и где произошло событие.
Это огромная планета
В прошлом я был виноват в том, что игнорировал то, что на этой планете есть и другие страны, помимо моей. В то время это казалось хорошей идеей, но это ВСЕГДА приводило к проблемам, головным болям и потере времени впустую. ВСЕГДА учитывайте все часовые пояса.
C #
DateTime хорошо отображается в строке в C #. Метод ToString (формат строки) компактен и удобен для чтения.
Например
SQL сервер
Кроме того, если вы читаете свою базу данных отдельно от интерфейса приложения, то dateTimes приятно читать с первого взгляда, а выполнение вычислений над ними несложно.
Например
Стандарт даты ISO8601
Если вы используете SQLite, этого у вас нет, поэтому вместо этого используйте текстовое поле и сохраните его в формате ISO8601, например.
«2013-01-27T12: 30: 00 + 0000»
Ноты:
Используется 24-часовой формат *
Часть смещения времени (или +0000) в стандарте ISO8601 напрямую сопоставляется со значением долготы координаты GPS (без учета перехода на летнее время или по стране).
Например
... где ± относится к восточному или западному направлению.
Поэтому стоит подумать, стоит ли хранить долготу, широту и высоту вместе с данными. Это зависит от приложения.
ISO8601 - это международный формат.
В вики можно найти более подробную информацию по адресу http://en.wikipedia.org/wiki/ISO_8601 .
Дата и время сохраняются в международном формате, а смещение записывается в зависимости от того, где в мире было сохранено время.
По моему опыту, всегда необходимо сохранять полную дату и время, независимо от того, думаю ли я, когда я начинаю проект. ISO8601 - это очень хороший и надежный способ сделать это.
Дополнительная консультация бесплатно
Также стоит сгруппировать события в цепочку. Например, при записи гонки все событие может быть сгруппировано по racer, race_circuit, circuit_checkpoints и circuit_laps.
По моему опыту, также целесообразно определить, кто сохранил запись. Либо как отдельная таблица, заполняемая через триггер, либо как дополнительный столбец в исходной таблице.
Чем больше вы вкладываете, тем больше вы получаете
Я полностью понимаю желание экономить пространство, насколько это возможно, но я редко делал это за счет потери информации.
Эмпирическое правило с базами данных гласит, что, как сказано в названии, база данных может сказать вам столько, сколько у нее есть данные, и может быть очень дорого возвращаться к историческим данным, заполняя пробелы.
Решение состоит в том, чтобы исправить это с первого раза. Это, конечно, легче сказать, чем сделать, но теперь у вас должно быть более глубокое представление об эффективном проектировании базы данных, и впоследствии у вас будет гораздо больше шансов сделать это правильно с первого раза.
Чем лучше будет ваш первоначальный проект, тем дешевле будет впоследствии ремонт.
Я говорю все это только потому, что если бы я мог вернуться в прошлое, то это то, что я бы сказал себе, когда туда попал.
источник
Просто сохраните обычную дату и время и игнорируйте все остальное. Зачем тратить лишнее время на написание кода, который загружает int, манипулирует им и преобразует в datetime, если вы можете просто загрузить datetime?
источник
DATETIME
тип данных занимает 4 байта для хранения, в то время как,SMALLINT
например, только четверть байта . Нет большой разницы, если у вас всего несколько тысяч строк, но если у вас много миллионов строк, как у многих компаний, тогда ваша экономия места будет значительной.поскольку вы не упомянули об этом, если вы используете SQL Server 2008, вы можете использовать тип данных time, иначе использовать минуты с полуночи
источник
SQL Server фактически хранит время в виде долей дня. Например, 1 целый день = значение 1. 12 часов - это значение 0,5.
Если вы хотите сохранить значение времени без использования типа DATETIME, сохранение времени в десятичной форме подойдет для этого, а также упростит преобразование в DATETIME.
Например:
Для сохранения значения в формате DECIMAL (9,9) потребуется 5 байтов. Однако, если точность не имеет первостепенного значения, REAL будет занимать только 4 байта. В любом случае совокупный расчет (т.е. среднее время) может быть легко рассчитан для числовых значений, но не для типов данных / времени.
источник
Я бы преобразовал их в целое число (ЧЧ * 3600 + ММ * 60) и сохранил бы его таким образом. Небольшой размер хранилища, но с ним достаточно легко работать.
источник
Если вы используете MySQL, используйте тип поля TIME и связанные функции, которые поставляются с TIME.
00:00:00 - стандартный формат времени unix.
Если вам когда-нибудь придется оглянуться назад и просмотреть таблицы вручную, целые числа могут сбить с толку больше, чем фактическая отметка времени.
источник
Попробуйте smalldatetime. Он может не дать вам того, что вы хотите, но он поможет вам в ваших будущих потребностях в манипуляциях с датой / временем.
источник
Вы уверены, что вам когда-нибудь понадобятся только часы и минуты? Если вы хотите сделать с ним что-нибудь значимое (например, вычислить промежутки времени между двумя такими точками данных), отсутствие информации о часовых поясах и летнем времени может дать неверные результаты. Часовые пояса, возможно, не применяются в вашем случае, но летнее время, безусловно, будет.
источник
Вместо минут после полуночи мы сохраняем это как 24-часовые часы, как SMALLINT.
09:12 = 912 14:15 = 1415
при обратном преобразовании в "удобочитаемую форму" мы просто вставляем двоеточие ":" два символа справа. Если нужно, введите нули влево. Сохраняет математические данные в каждом случае и использует немного меньше байтов (по сравнению с varchar), а также обеспечивает, чтобы значение было числовым (а не буквенно-цифровым)
Довольно глупо ... в MS SQL уже много лет должен был быть тип данных TIME ИМХО ...
источник
Я думаю, вы просите переменную, которая будет хранить минуты в виде числа. Это можно сделать с помощью различных типов целочисленных переменных:
Затем в своей программе вы можете просто просмотреть это в желаемой форме, вычислив:
Проблема возникает, когда вы запрашиваете эффективность использования. Но если у вас мало времени, просто используйте BigInt, допускающий значение NULL, для хранения значения минут.
Значение null означает, что время еще не было записано.
Теперь я объясню это в форме кругосветного путешествия в космос.
К сожалению, столбец таблицы хранит только один тип. Следовательно, вам нужно будет создать новую таблицу для каждого типа по мере необходимости.
Например:
Если MinutesInput = 0 .. 255, используйте TinyInt (преобразовать, как описано выше).
Если MinutesInput = 256 .. 131071, тогда используйте SmallInt (Примечание: минимальное значение SmallInt равно -32 768. Следовательно, отрисуйте и добавьте 32768 при сохранении и извлечении значения, чтобы использовать полный диапазон перед преобразованием, как указано выше).
Если MinutesInput = 131072 .. 8589934591, используйте Int (примечание: отмените значение и добавьте 2147483648 при необходимости).
Если MinutesInput = 8589934592 .. 36893488147419103231, используйте BigInt (примечание: при необходимости добавьте и отрицайте 9223372036854775808).
Если MinutesInput> 36893488147419103231, я бы лично использовал VARCHAR (X), увеличивая X по мере необходимости, поскольку char - это байт. Мне придется вернуться к этому ответу позже, чтобы описать это полностью (или, может быть, другой stackoverflowee сможет закончить этот ответ).
Поскольку для каждого значения, несомненно, потребуется уникальный ключ, эффективность базы данных будет очевидна только в том случае, если диапазон хранимых значений представляет собой хорошее сочетание между очень маленьким (около 0 минут) и очень высоким (больше 8589934591).
Пока сохраняемые значения не достигнут числа, превышающего 36893488147419103231, у вас также может быть один столбец BigInt для представления ваших минут, поскольку вам не нужно тратить Int на уникальный идентификатор и другой int для хранения значения минут.
источник
Как предложила Кристен, экономия времени в формате UTC может помочь лучше.
Убедитесь, что вы используете 24-часовые часы, потому что в UTC не используется меридиан AM или PM.
Пример:
По-прежнему предпочтительнее использовать стандартный четырехзначный формат.
источник
Сохраните
ticks
какlong
/bigint
, которые в настоящее время измеряются в миллисекундах. Обновленное значение можно найти, посмотрев наTimeSpan.TicksPerSecond
значение.Большинство баз данных имеют тип DateTime, который автоматически сохраняет время в виде тиков за кулисами, но в случае некоторых баз данных, например SqlLite, хранение тиков может быть способом сохранения даты.
Большинство языков позволяют легко преобразовать
Ticks
→TimeSpan
→Ticks
.пример
В C # код будет:
Однако имейте в виду, потому что в случае с SqlLite, который предлагает лишь небольшое количество различных типов:
INT
,REAL
иVARCHAR
необходимо будет сохранить количество тактов в виде строки или двухINT
вместе взятых ячеек. Это потому, что этоINT
32-битное числоBIGINT
со знаком, тогда как это 64- битное число со знаком.Заметка
Однако лично я предпочитаю хранить дату и время в виде
ISO8601
строки.источник
ИМХО, какое лучшее решение в некоторой степени зависит от того, как вы храните время в остальной части базы данных (и остальной части вашего приложения)
Лично я работал с SQLite и стараюсь всегда использовать временные метки unix для хранения абсолютного времени, поэтому, имея дело с временем дня (как вы просите), я делаю то, что Глен Солсберри пишет в своем ответе, и сохраняю количество секунд с полуночи
При таком общем подходе люди (включая меня!), Читающие код, будут менее запутаны, если я везде использую один и тот же стандарт.
источник