데이터베이스에 시간(hh:mm)을 저장하는 가장 좋은 방법
시간을 데이터베이스 테이블에 저장하고 싶지만 시간과 분만 저장하면 됩니다.DATTIME을 사용하여 날짜의 다른 구성 요소를 무시할 수도 있지만, 실제로 필요한 것보다 더 많은 정보를 저장하지 않고 이를 수행하는 가장 좋은 방법은 무엇입니까?
자정이 지난 시간(분)의 정수로 저장할 수 있습니다.
예를 들면
0 = 00:00
60 = 01:00
252 = 04:12
그러나 시간을 재구성하기 위해 코드를 작성해야 하지만, 그것은 까다로울 수 없습니다.
SQL Server 2008+를 사용하는 경우 데이터 유형을 고려하십시오. 자세한 사용 예가 있는 SQLTeam 기사.
DATTIME 시작 DATTIME 종료
대신 event_start 및 event_end와 같은 레이블이 지정된 두 개의 DATTIME 값을 사용해 주시기 바랍니다.
시간은 복잡한 비즈니스입니다.
현재 대부분의 세계는 옳든 그르든 대부분의 측정에 대해 거부 기반 미터법을 채택했습니다.이것은 전체적으로 좋습니다, 왜냐하면 적어도 우리 모두는 g가 ml이고, 입방 센티미터라는 것에 동의할 수 있기 때문입니다.적어도 대략 그렇습니다.미터법은 많은 결함이 있지만, 적어도 국제적으로 일관되게 결함이 있습니다.
그러나 시간이 지남에 따라 1000밀리초, 60초에서 1분, 60분에서 1시간, 매 반나절마다 12시간, 해당 월과 연도에 따라 약 30일, 각 국가마다 시간 오프셋이 있으며 각 국가의 시간 형식도 다릅니다.
소화하기에는 양이 많지만, 이렇게 복잡한 시나리오가 간단한 해결책을 갖는 것은 결국 불가능합니다.
어떤 코너는 자를 수 있지만, 그렇게 하지 않는 것이 더 현명한 곳도 있습니다.
여기서 가장 중요한 답변은 자정 이후의 정수를 저장하는 것이 완벽하게 합리적일 수 있다는 것을 시사하지만, 저는 그렇게 하는 것을 피하는 법을 배웠습니다.
두 개의 DATTIME 값을 구현하는 이유는 정확도, 해상도 및 피드백을 높이기 위해서입니다.
이것들은 모두 설계가 바람직하지 않은 결과를 생성할 때 매우 유용합니다.
필요한 것보다 더 많은 데이터를 저장하고 있습니까?
처음에는 필요한 것보다 더 많은 정보가 저장되어 있는 것처럼 보일 수 있지만, 이 문제를 해결할 충분한 이유가 있습니다.
이 추가 정보를 저장하면 장기적으로 시간과 노력을 절약할 수 있습니다. 왜냐하면 누군가가 시간이 얼마나 걸렸는지를 알게 되면, 그들은 추가적으로 그 행사가 언제 어디서 열렸는지도 알고 싶어할 것이기 때문입니다.
그것은 거대한 행성입니다.
과거에, 저는 이 행성에 제 나라 외에도 다른 나라들이 있다는 것을 무시한 죄를 지었습니다.그 당시에는 좋은 생각처럼 보였지만, 이것은 항상 문제와 두통을 야기했고 나중에 시간을 낭비했습니다.항상 모든 시간대를 고려합니다.
C#
DateTime은 C#의 문자열로 렌더링됩니다.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-27 T12:30:00+0000"
주의:
이것은 24시간 시계를 사용합니다*
ISO8601의 시간 오프셋(또는 +0000) 부분은 GPS 좌표의 경도 값에 직접 매핑됩니다(일광 절약 또는 국가 전체를 고려하지 않음).
예.
TimeOffset=(±Longitude.24)/360
...여기서 ±는 동쪽 또는 서쪽 방향을 나타냅니다.
따라서 경도, 위도 및 고도를 데이터와 함께 저장할 가치가 있는지 고려해 볼 가치가 있습니다.이는 용도에 따라 달라집니다.
ISO8601은 국제 포맷입니다.
위키는 http://en.wikipedia.org/wiki/ISO_8601 에서 더 자세한 정보를 얻을 수 있습니다.
날짜와 시간은 국제 시간으로 저장되고 오프셋은 세계 어디에 시간이 저장되었는지에 따라 기록됩니다.
제 경험에 따르면 프로젝트를 시작할 때 날짜와 시간을 모두 저장해야 합니다.ISO8601은 매우 우수하고 미래에 대비할 수 있는 방법입니다.
무료 추가 조언
또한 이벤트를 체인처럼 그룹화할 가치가 있습니다.예를 들어 경기를 기록할 경우, 전체 이벤트를 레이서, 레이스_서킷, 서킷_체크포인트 및 서킷_랩별로 그룹화할 수 있습니다.
제 경험상, 누가 기록을 저장했는지 확인하는 것도 현명합니다.트리거를 통해 채워지는 별도의 테이블 또는 원래 테이블 내의 추가 열로 구성됩니다.
더 많이 넣을수록 더 많이 나옵니다.
저는 공간을 최대한 절약하고 싶은 욕구를 완전히 이해하지만, 정보를 잃는 대가로 그렇게 하는 경우는 거의 없습니다.
데이터베이스에 대한 경험의 법칙은 제목에서 알 수 있듯이 데이터베이스는 데이터가 있는 만큼만 알려줄 수 있으며, 과거 데이터를 다시 조사하여 공백을 메우는 데 많은 비용이 소요될 수 있습니다.
해결책은 한 번에 정답을 맞추는 것입니다.이것은 확실히 말하기는 쉽지만, 이제 효과적인 데이터베이스 설계에 대한 심층적인 통찰력을 갖게 되고, 그에 따라 처음에 올바르게 적용될 가능성이 훨씬 더 높아집니다.
초기 설계가 우수할수록 나중에 수리 비용이 줄어듭니다.
저는 단지 이 모든 것을 말할 뿐입니다. 왜냐하면 제가 과거로 돌아갈 수 있다면, 그것은 제가 그곳에 도착했을 때 제 자신에게 말할 것이기 때문입니다.
일정한 날짜 시간만 저장하고 다른 모든 것은 무시합니다.날짜 시간만 로드할 수 있는데 int를 로드하고, 이를 조작하고, 날짜 시간으로 변환하는 코드를 작성하는 데 왜 추가 시간을 소비합니까?
SQL Server 2008에 있는 경우 시간 데이터 유형을 사용하거나 자정 이후 분을 사용할 수 있습니다.
MySQL을 사용하는 경우 TIME 필드 유형과 TIME과 함께 제공되는 관련 기능을 사용합니다.
00:00:00은 표준 UNIX 시간 형식입니다.
만약 여러분이 손으로 표를 돌아보고 검토해야 한다면, 정수는 실제 타임스탬프보다 더 혼란스러울 수 있습니다.
SQL Server는 실제로 하루의 일부로 시간을 저장합니다.예를 들어, 1 종일 = 1.12시간의 값은 0.5입니다.
DATTIME 유형을 사용하지 않고 시간 값을 저장하려는 경우 시간을 10진수 형식으로 저장하는 것이 적합할 뿐만 아니라 DATTIME으로 쉽게 변환할 수 있습니다.
예:
SELECT CAST(0.5 AS DATETIME)
--1900-01-01 12:00:00.000
값을 DECIMAL(9,9)로 저장하면 5바이트가 사용됩니다.그러나 정밀도가 가장 중요하지 않은 경우 REAL은 4바이트만 사용합니다.두 경우 모두 집계 계산(즉, 평균 시간)은 숫자 값으로 쉽게 계산할 수 있지만 데이터/시간 유형에서는 계산할 수 없습니다.
저는 그것들을 정수(HH*3600 + MM*60)로 변환하여 저장할 것입니다.스토리지 크기는 작지만 작업하기에 충분히 쉽습니다.
자정이 넘은 분 대신 24시간 시계로 저장합니다. SALLINT로 저장합니다.
09:12 = 912 14:15 = 1415
"인간이 읽을 수 있는 형태"로 다시 변환할 때는 오른쪽에서 콜론 ":" 두 글자를 삽입하면 됩니다.필요한 경우 0이 있는 왼쪽 패드입니다.수학을 모든 방식으로 저장하고, (바르샤르에 비해) 바이트 수를 적게 사용하며, 값이 영숫자가 아닌 숫자여야 합니다.
꽤 바보같지만... MS SQL에 이미 여러 해 동안 TIME 데이터 유형이 있었어야 했습니다. IMHO...
잠시 후에 시도해 보십시오.원하는 것을 얻지 못할 수도 있지만 날짜/시간 조작에 있어 향후 필요한 사항에 도움이 될 것입니다.
시간과 분만 필요하십니까?시간대 및 DST에 대한 정보가 없는 경우(예: 이러한 두 데이터 지점 간의 계산 시간 범위) 의미 있는 작업을 수행하려는 경우 잘못된 결과가 나타날 수 있습니다.당신의 경우에는 표준 시간대가 적용되지 않을 수도 있지만, DST는 분명히 적용될 것입니다.
제 생각에 당신이 요구하는 것은 분을 숫자로 저장할 변수입니다.이 작업은 다양한 유형의 정수 변수를 사용하여 수행할 수 있습니다.
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;
사용할 효율성을 요청하는 문제가 발생합니다.그러나 시간이 부족하다면 null 가능한 BigInt를 사용하여 분 값을 저장하십시오.
null 값은 시간이 아직 기록되지 않았음을 의미합니다.
이제, 저는 우주 왕복의 형태로 설명하겠습니다.
안타깝게도 표 열에는 단일 유형만 저장됩니다.따라서 필요에 따라 각 유형에 대해 새 테이블을 만들어야 합니다.
예:
시간(If Minutes입력 = 0..255 그런 다음 TinyInt(위에서 설명한 대로 변환)를 사용합니다.
시간(If Minutes입력 = 256..131071 그런 다음 SmallInt를 사용합니다(참고: SmallInt의 최소값은 -32,768입니다).따라서 위와 같이 변환하기 전에 전체 범위를 활용하기 위해 값을 저장하고 검색할 때 32768을 negative하고 추가합니다.
시간(If Minutes입력 = 131072..8589934591 그런 다음 Int를 사용합니다(참고: 2147483648을 제거하고 필요에 따라 추가).
시간(If Minutes입력 = 8589934592..36893488147419103231을 사용한 후 BigInt를 사용합니다(참고:필요에 따라 922372036854775808을 추가하고 무효화합니다.
시간(If Minutes입력 > 36893488147419103231 그러면 나는 개인적으로 문자가 바이트이기 때문에 필요에 따라 X를 증가시키는 VARCHAR(X)를 사용할 것입니다.나중에 이 답변을 자세히 설명하기 위해 이 답변을 다시 검토해야 합니다(또는 동료 스택 오버플로피가 이 답변을 끝낼 수도 있습니다).
각 값에는 의심할 여지 없이 고유한 키가 필요하므로 저장된 값의 범위가 매우 작은(0분 가까이) 경우와 매우 높은(8589934591 이상) 경우에만 데이터베이스의 효율성이 명백해집니다.
저장 중인 값이 실제로 36893488147419103231보다 큰 숫자에 도달할 때까지 고유 식별자에 Int를 낭비하고 분 값을 저장하기 위해 다른 int를 낭비할 필요가 없으므로 분을 나타내는 단일 BigInt 열을 가질 수 있습니다.
UTC 형식으로 시간을 절약하는 것이 Kristen이 제안한 것처럼 더 도움이 될 수 있습니다.
UTC에는 자오선 AM 또는 PM이 사용되지 않으므로 24시간 시계를 사용해야 합니다.
예:
- 오전 4:12 - 0412
- 오전 10:12 - 1012
- 오후 2:28 - 1428
- 오후 11:56 - 2356
그래도 표준 4자리 형식을 사용하는 것이 좋습니다.
저장 위치ticks로서long/bigint현재 밀리초 단위로 측정됩니다.업데이트된 값은 다음을 참조하여 확인할 수 있습니다.TimeSpan.TicksPerSecond가치.
대부분의 데이터베이스에는 자동으로 시간을 배경 뒤에 눈금으로 저장하는 DateTime 유형이 있지만, 일부 데이터베이스(예: SqlLite)의 경우 눈금을 저장하는 것이 날짜를 저장하는 방법이 될 수 있습니다.
대부분의 언어는 에서 쉽게 변환할 수 있습니다.Ticks→TimeSpan→Ticks.
예
C#에서 코드는 다음과 같습니다.
long TimeAsTicks = TimeAsTimeSpan.Ticks;
TimeAsTimeSpan = TimeSpan.FromTicks(TimeAsTicks);
그러나 SqlLite의 경우 소수의 서로 다른 유형만 제공하므로 주의하십시오.INT,REAL그리고.VARCHAR눈금 수를 하나 또는 두 개의 문자열로 저장해야 합니다.INT세포를 합친 것.왜냐하면.INT32비트 부호 있는 숫자인 반면BIGINT64비트 부호 있는 숫자입니다.
메모
하지만 저의 개인적인 선호는 날짜와 시간을 저장하는 것입니다.ISO8601현을 매다
IMHO가 가장 적합한 솔루션은 데이터베이스의 나머지 부분(및 애플리케이션의 나머지 부분)에 시간을 저장하는 방법에 따라 달라집니다.
개인적으로 저는 SQLite와 함께 작업했으며 절대 시간을 저장하기 위해 항상 유닉스 타임스탬프를 사용하려고 노력합니다. 그래서 하루 중 시간을 처리할 때(당신이 요청하는 대로) 글렌 솔즈베리가 답변에 기록한 대로 수행하고 자정 이후의 초 수를 저장합니다.
이 일반적인 접근 방식을 취할 때 코드를 읽는 사람들(나 포함!)은 모든 곳에서 동일한 표준을 사용하면 덜 혼란스러워집니다.
언급URL : https://stackoverflow.com/questions/538739/best-way-to-store-time-hhmm-in-a-database
'programing' 카테고리의 다른 글
| Twitter 부트스트랩 Modal Close에 함수 바인딩 (0) | 2023.05.28 |
|---|---|
| 장치 토큰(NSData)을 NS 문자열로 변환하려면 어떻게 해야 합니까? (0) | 2023.05.28 |
| 병합 후 분기에서 수행할 작업 (0) | 2023.05.28 |
| 파일 경로를 파일 URI로 변환하시겠습니까? (0) | 2023.05.28 |
| 이클립스에서 안드로이드 프로젝트에 활동을 추가하는 가장 좋은 방법은 무엇입니까? (0) | 2023.05.28 |