문제

어느 것:

~이다 그만큼 SQL Server 2008+에 날짜와 시간을 저장하는 권장 방법?

정밀도의 차이 (및 아마도 저장 공간)의 차이를 알고 있지만 지금 당장을 무시하고 무엇을 사용 해야하는지에 대한 모범 사례 문서가 있습니까? datetime2 뿐?

도움이 되었습니까?

해결책

MSDN 문서 날짜 시간 사용 권장합니다 dateTime2. 추천은 다음과 같습니다.

사용 time, date, datetime2 그리고 datetimeoffset 새로운 작업을위한 데이터 유형. 이러한 유형은 SQL 표준과 일치합니다. 그들은 더 휴대 성입니다. time, datetime2 그리고 datetimeoffset더 많은 초 정밀도를 제공하십시오. datetimeoffset 전 세계적으로 배포 된 애플리케이션에 대한 시간대 지원을 제공합니다.

DATETIME2는 날짜 범위가 클수록, 기본 비율이 커지고 선택적 사용자 지정 정밀도를 갖습니다. 또한 사용자 지정 정밀도에 따라 스토리지가 적을 수 있습니다.

다른 팁

DATETIME2 날짜 범위는 "0001 / 01 / 01"까지 "9999 / 12 / 31"입니다. DATETIME 유형은 1753-9999 년에만 지원합니다.

또한 필요하다면 DATETIME2 시간 측면에서 더 정확할 수 있습니다. DateTime은 3 1/3 밀리 초로 제한됩니다 DATETIME2 100ns까지 정확할 수 있습니다.

두 유형 모두 맵입니다 System.DateTime .NET에서 - 차이가 없습니다.

선택의 여지가 있다면 사용하는 것이 좋습니다. DATETIME2 언제든지 가능할 때. 사용한 이점이 없습니다 DATETIME (후진 호환성을 제외하고) - 당신은 문제가 적을 것입니다 (날짜가 범위를 벗어나고 번거 로움을 겪게됩니다).

플러스 : 날짜 만 필요하면 (시간 부분이 없음) 날짜를 사용하십시오. DATETIME2 그리고 당신도 공간을 절약합니다! :-) 시간 만 동일합니다 - 사용 TIME. 그것이 바로 이러한 유형이있는 것입니다!

dateTime2 (오래된 앱 호환성)을 제외한 대부분의 측면에서 승리합니다.

  1. 더 큰 값 범위
  2. 더 나은 정확성
  3. 더 작은 저장 공간 (선택적 사용자 지정 정밀도가 지정된 경우)

SQL Date and time data types compare - datetime,datetime2,date,TIME

다음 사항에 유의하십시오

  • 통사론
    • dateTime2 [(분수 초 정밀 => 스토리지 크기 아래에서보세요)
  • 정밀, 규모
    • 100ns의 정확도로 0 ~ 7 자리.
    • 기본 정밀도는 7 자리입니다.
  • 스토리지 크기
    • 3 미만의 정밀도에 대한 6 바이트;
    • 정밀 3 및 4에 대한 7 바이트.
    • 다른 모든 정밀도 8 바이트가 필요합니다.
  • dateTime2 (3) DateTime과 동일한 수의 숫자가 있지만 8 바이트 대신 7 바이트의 스토리지를 사용합니다 (sqlhints-dateTime vs dateTime2)
  • 자세한 내용을 찾으십시오 DateTime2 (TransAct-SQL MSDN 기사)

이미지 출처 :MCTS 자체 진행중인 교육 키트 (Exam 70-432) : Microsoft® SQL Server® 2008- 구현 및 유지 보수3 장 : 테이블 -> 레슨 1 : 테이블 만들기 -> 페이지 66

@MARC_S 및 @ADAM_POWARD와 동의합니다. DateTime2는 앞으로 선호되는 방법입니다. 날짜가 더 넓고 정밀도가 높으며 정밀도에 따라 동일하거나 저장을 사용합니다.

그러나 토론이 놓친 한 가지 ...
@MARC_S 상태 : Both types map to System.DateTime in .NET - no difference there. 이것은 맞습니다. 그러나 역전은 사실이 아닙니다... 날짜 범위 검색을 수행 할 때 중요합니다 (예 : "2010 년 5 월 5 일에 수정 된 모든 레코드를 찾으십시오").

.NET의 버전 Datetime 비슷한 범위와 정밀도가 있습니다 DateTime2. .NET를 매핑 할 때 Datetime 오래된 SQL로 내려갑니다 DateTime an 암시 적 반올림이 발생합니다. 오래된 SQL DateTime 3 밀리 초로 정확합니다. 이것은 그것을 의미합니다 11:59:59.997 하루가 끝날 때까지 가깝습니다. 더 높은 것은 다음 날까지 반올림됩니다.

이 시도 :

declare @d1 datetime   = '5/5/2010 23:59:59.999'
declare @d2 datetime2  = '5/5/2010 23:59:59.999'
declare @d3 datetime   = '5/5/2010 23:59:59.997'
select @d1 as 'IAmMay6BecauseOfRounding', @d2 'May5', @d3 'StillMay5Because2msEarlier'

이 암시 적 반올림을 피하는 것은 DateTime2로 이동하는 중요한 이유입니다. 날짜의 암시 적 반올림은 분명히 혼란을 유발합니다.

거의 모든 답과 의견은 단점에 대한 장단점에 무겁습니다. 다음은 지금까지 모든 장단점과 한 번만 언급했거나 전혀 언급하지 않은 중요한 단점 (아래 #2)의 요약입니다.

  1. 장점 :

1.1. 더 많은 ISO 준수 (ISO 8601) (실제로 이것이 어떻게 작동하는지 모르겠지만).

1.2. 더 많은 범위 (1/1/0001 ~ 12/31/9999 vs. 1/1/1753-12/31/9999) (1753 년 이전의 추가 범위는 Ex., Ex.를 제외하고는 사용되지 않을 수 있습니다. 역사적, 천문학적, 지질 학적 등. 앱).

1.3. .NET의 범위와 정확히 일치합니다 DateTime 유형의 범위 (값이 대상 유형의 범위 내에있는 경우 특수 코딩없이 앞뒤로 변환하지만 아래의 CON # 2.1을 제외하고는 오류 / 반올림이 발생합니다).

1.4. 더 많은 정밀도 (100 나노초 일명 0.000,000,1 초 vs. 3.33 밀리 초 일명 0.003,33 초) (엔지니어링 / 과학 앱에서는 Ex.를 제외하고는 추가 정밀도가 사용되지 않을 수 있지만).

1.5. 구성된 경우 비슷한 (Iman Abidi가 주장한 것과 같이 "동일하지 않은"(3.33 millisec에서와 같이) 1 Millisec에서와 같이) 정밀도 DateTime, 공간이 적은 공간 (7 대 8 바이트)을 사용하지만 물론, 당신은 정밀한 혜택을 잃어 버릴 것입니다.이 혜택 중 하나 일 가능성이 높습니다.

  1. 단점 :

2.1. 매개 변수를 .NET에 전달할 때 SqlCommand, 당신은 지정해야합니다 System.Data.SqlDbType.DateTime2 SQL Server 외부에서 값을 전달하는 경우 DateTime기본값으로 인해 범위 및/또는 정밀도가 System.Data.SqlDbType.DateTime.

2.2. 숫자 값 및 연산자를 사용하여 SQL Server 표현식에서 다음을 수행하기 위해 부동 소수점 숫자 (Min Date Time 이후의 날) 값으로 쉽게 변환 할 수 없습니다.

2.2.1. 일 또는 부분 일을 추가하거나 빼십시오. 참고 : 사용 DateAdd 날짜 시간의 모든 부분이 아닌 경우 다중 고려해야 할 때 해결 방법으로서의 기능은 사소한 것이 아닙니다.

2.2.2. "연령"계산 목적으로 두 날짜 시간의 차이를 취하십시오. 참고 : 단순히 SQL Server를 사용할 수는 없습니다 DateDiff 대신 작동하지 않기 때문에 기능합니다 age 대부분의 사람들이 예상대로 두 날짜 시간이 해당 단위의 작은 부분에 대해서도 지정된 단위의 캘린더 / 시계 날짜 시간 경계를 넘어서는 경우 해당 단위 대 VS 중 1 개로 차이를 반환합니다. . 0. 예를 들어, DateDiff 안에 Day날짜 시간이 다른 일정에있는 경우 (예 :“1999-12-31 23 : 59 : 59.9999999”및“2000-01-”라면 1 밀리 초 단위의 두 날짜 시간은 1 vs. 0 (일)입니다. 01 00 : 00 : 00.0000000”). 달력 일을 건너지 않도록 이동하면 동일한 1 밀리 초의 차이 날짜 시간이 Day0 (일).

2.2.3. 가져 가라 Avg 먼저 "float"로 변환 한 다음 다시 DateTime.

참고 : 변환합니다 DateTime2 숫자는 1970 년보다 여전히 값이 여전히 남아 있다고 가정하는 다음 공식과 같은 작업을 수행해야합니다 (즉, 추가 범위와 217 년이 더 남아 있음을 의미합니다. 참고 : 참고 : 당신은 할 수 없습니다. 숫자 오버플로 문제가 발생할 수 있으므로 추가 범위를 허용하도록 공식을 조정하기 만하면됩니다.

25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0 - 원천: " https://siderite.blogspot.com/2015/08/how-to-translate-t-sql-datetime2-to.html

물론, 당신도 할 수도 있습니다 Cast 에게 DateTime 먼저 (그리고 필요한 경우 다시 DateTime2), 그러나 당신은 정밀도와 범위를 잃을 것입니다 (1753 년 이전) 혜택 DateTime2 vs. DateTime 그것은 두 번째로 가장 큰 것과 동시에 2 개의 가장 적은 2 명에 불과합니다. 이는 부동 소수점 숫자 (# of Days)로의 암시 적 / 쉬운 전환을 잃을 때 왜 그것을 사용하는지에 대한 의문을 제기합니다. "(vs. DateDiff) / Avg Calcs의 혜택은 제 경험에서 큰 혜택입니다.

btw, the Avg 데이트 타임은 (또는 적어도 ~해야 한다 중요한 사용 사례. a) 날짜 시간 (일반적인 기본 날짜 시간)이 지속 시간을 나타내는 데 사용되기 때문에 평균 기간을 얻는 것 외에도 (일반적인 관행) b) 평균 날짜에 대한 대시 보드 유형 통계를 얻는 것이 유용합니다. 시간은 행의 범위 / 그룹의 날짜 시간 열에 있습니다. c) 표준 (또는 적어도 ~해야 한다 표준) Ad-Hoc Query 열에서 값을 모니터링 / 문제를 해결하거나 더 이상 유효하지 않을 수있는 열의 값을 모니터링 / 문제 해결하십시오. Min, Avg 그리고 Max 해당 값과 관련된 날짜 시간 스탬프.

DateTime2는 문제의 현장에 지금 ()을 쓰려고하는 액세스 개발자라면 혼란을 일으킨다. 방금 액세스 -> SQL 2008 R2 마이그레이션을 수행했으며 모든 DateTime 필드를 AS DateTime2에 넣었습니다. 가치가 폭격 된 상태에서 지금 ()와 레코드를 추가합니다. 2012 년 1 월 1 일 오후 2:53:04에는 괜찮지 만 2012 년 1 월 10 일 오후 2:53:04에는 아닙니다.

일단 캐릭터가 차이를 만들었습니다. 누군가가 도움이되기를 바랍니다.

다음은 스토리지 크기 (바이트)와 SmallDateTime, DateTime, DateTime2 (0) 및 DateTime2 (7) 간의 정밀도의 차이를 보여주는 예입니다.

DECLARE @temp TABLE (
    sdt smalldatetime,
    dt datetime,
    dt20 datetime2(0),
    dt27 datetime2(7)
)

INSERT @temp
SELECT getdate(),getdate(),getdate(),getdate()

SELECT sdt,DATALENGTH(sdt) as sdt_bytes,
    dt,DATALENGTH(dt) as dt_bytes,
    dt20,DATALENGTH(dt20) as dt20_bytes,
    dt27, DATALENGTH(dt27) as dt27_bytes FROM @temp

반환

sdt                  sdt_bytes  dt                       dt_bytes  dt20                 dt20_bytes  dt27                         dt27_bytes
2015-09-11 11:26:00  4          2015-09-11 11:25:42.417  8         2015-09-11 11:25:42  6           2015-09-11 11:25:42.4170000  8

따라서 정보를 두 번째로 저장하려면 밀리 초가 아닌 두 번째로 저장하려면 DateTime 또는 DateTime2 (7) 대신 DateTime2 (0)를 사용하면 각각 2 바이트를 저장할 수 있습니다.

날짜 문자열의 해석 datetime 그리고 datetime2 비 US를 사용할 때도 다를 수 있습니다 DATEFORMAT 설정. 예를 들어

set dateformat dmy
declare @d datetime, @d2 datetime2
select @d = '2013-06-05', @d2 = '2013-06-05'
select @d, @d2

이것은 반환됩니다 2013-05-06 (즉, 5 월 6 일) datetime, 그리고 2013-06-05 (예 : 6 월 5 일) datetime2. 그러나 dateformat 로 설정 mdy, 둘 다 @d 그리고 @d2 반품 2013-06-05.

그만큼 datetime 행동과 상충되는 것 같습니다 MSDN 문서SET DATEFORMAT 어떤 상태 : 일부 특성 문자열 형식 (예 : ISO 8601)은 DateFormat 설정과 독립적으로 해석됩니다.. 분명히 사실이 아닙니다!

내가 이것에 물릴 때까지 나는 항상 yyyy-mm-dd 언어 / 로케일 설정에 관계없이 날짜는 바로 처리됩니다.

증가하는 동안 정도 ~와 함께 dateTime2, 일부 고객은 지원하지 않습니다 데이트, 시각, 또는 dateTime2 그리고 당신은 문자열 문자로 변환하도록 강요합니다. 특히 Microsoft는 이러한 데이터 유형에 대한 "다운 레벨"ODBC, OLE DB, JDBC 및 SQLCLIENT 문제를 언급하며 차트 각각이 유형을 매핑 할 수있는 방법을 보여줍니다.

값 인 경우 호환성 지나치게 정밀하게 사용하십시오 날짜 시간

오래된 질문 ...하지만 여기에 아무도 언급하지 않은 것을 추가하고 싶습니다 ... (참고 : 이것은 내 자신의 관찰이므로 참조를 요구하지 마십시오).

필터 기준으로 사용하면 DateTime2가 더 빠릅니다.

tldr :

SQL 2016에는 정확한 시간을 몇 초까지 저장해야했기 때문에 수십만 행과 DateTime Column Entry_time이있는 테이블이있었습니다. 많은 조인과 하위 쿼리가있는 복잡한 쿼리를 실행하는 동안 다음과 같은 위치를 사용할 때 :

WHERE ENTRY_TIME >= '2017-01-01 00:00:00' AND ENTRY_TIME < '2018-01-01 00:00:00'

수백 행이 있었을 때 쿼리는 처음에는 괜찮 았지만 행의 수가 증가하면 쿼리 가이 오류를주기 시작했습니다.

Execution Timeout Expired. The timeout period elapsed prior
to completion of the operation or the server is not responding.

나는 WHERE 절을 제거했으며 예기치 않게 쿼리는 1 초 안에 실행되었지만 이제는 모든 날짜의 모든 행이 가져 왔습니다. 나는 위치 조항으로 내부 쿼리를 실행하고 85 초가 걸렸으며, 위치가 없으면 0.01 초가 걸렸다.

나는이 문제에 대해 여기에 많은 스레드를 발견했다. DateTime 필터링 성능

쿼리를 조금 최적화했습니다. 그러나 내가 얻은 실제 속도는 DateTime 열을 DateTime2로 변경하는 것입니다.

이제 이전에 시간을 초과 한 동일한 쿼리는 1 초도 채 걸리지 않습니다.

건배

에 따르면 이 기사, dateTime2를 사용하여 DateTime과 동일한 정밀도를 원한다면 단순히 DateTime2 (3)를 사용해야합니다. 이것은 당신에게 동일한 정밀도를 제공하고, 하나의 바이트를 더 많이 가져 가고, 확장 된 범위를 제공해야합니다.

나는 방금 한 가지 더 이점을 우연히 발견했다 DATETIME2: 파이썬의 버그를 피합니다 adodbapi 표준 라이브러리 인 경우 폭발하는 모듈 datetime 값은 0이 아닌 마이크로 초를 갖는 값이 전달됩니다 DATETIME 열이지만 열이 다음과 같이 정의되면 잘 작동합니다. DATETIME2.

Select ValidUntil + 1
from Documents

위의 SQL은 DateTime2 필드에서 작동하지 않습니다. 반환 및 오류 "오페라 타입 충돌 : DateTime2는 int와 호환되지 않습니다"

다음 날을 얻기 위해 1을 추가하는 것은 개발자들이 몇 년 동안 날짜로해온 일입니다. 이제 Microsoft에는이 간단한 기능을 처리 할 수없는 Super New DateTime2 필드가 있습니다.

"오래된 유형보다 더 나쁜이 새로운 유형을 사용합시다."나는 그렇게 생각하지 않는다!

제 생각에는 DATETIME2 저장하는 더 좋은 방법입니다 date, 그것은보다 효율성이 높기 때문입니다 DATETIME. ~ 안에 SQL Server 2008 당신이 사용할 수있는 DATETIME2, 날짜와 시간을 저장하고 6-8 bytes 저장하고 정밀도가 있습니다 100 nanoseconds. 따라서 더 큰 시간이 필요한 사람은 누구나 원할 것입니다 DATETIME2.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top