#title 날짜 데이터 형식 [[TableOfContents]] ==== 개요 ==== 성능의 기본은 데이터의 크기를 줄이는 것이다. 데이터의 크기를 결정하는 가장 기본적인 단계가 바로 컬럼에 대한 데이터 형식을 결정하는 일이다. 날짜의 경우 많은 데이터 형식으로 표현할 수 있기 때문에 사용의 용도에 맞게 적절한 데이터 형식을 사용하는 것이 좋다. 이 문서에서는 날짜를 표현하는 방식에 따른 장/단점을 성능의 관점으로 떠들어 보겠다. ==== 문자열 YYYYMMDD 형식 ==== YYYYMMDD형식 또는 YYYY-MM-DD형식의 문자열로 날짜를 저장하는 경우가 많이 있다. 문자열로 저장할 경우는 WHERE DT LIKE '200910%'과 같은 형식으로 월단위 조회가 매우 쉽다. 하지만 역시 8byte 또는 10byte를 써야 한다. 게다가 문자열이므로 숫자가 아닌 문자(예:A, B, C)와 같은 유효성에 대한 처리도 해주어야 한다. 또한 다음과 같은 쿼리의 경우는 내부적인 형변환이 일어나 풀스캔하게 되는 잠재적인 문제도 있다. {{{ SELECT ColA, ColB, ColC FROM TableA WHERE DT = 20091020; }}} 그럼 어찌하면 좋은가? 그저 YYYYMMDD형식이라면 int형으로 충분히 커버가 가능하다. 문자열 비교연산 알고리즘이 아무리 좋다고 해도 숫자보다 빠르겠는가? 또한 숫자만 들어오므로 유효성 문제가 문자형일때 보다는 좀 덜하다. 또한 내부적인 형변환 자체도 걱정하지 않아도 된다. 여러가지 장점이 있을 수 있겠지만 결국은 int형으로 커버가 가능하다는 것이다. 즉, 4byte로 저장이 가능하다는 것이다. 8byte보다는 4byte가 좋다. 인덱스를 만들어도 크기가 훨씬 적어질 것이다. 단, 문제는 월단위 연산이 조금 번거롭다는 것이다. SQL Server의 경우는 다음과 같이 해야 한다. {{{ DECLARE @DT char(8); SET @DT = '20091015'; --DT컬럼이 문자열 YYYYMMDD형식일 경우 SELECT ColA, ColB, ColC FROM TableA WHERE DT LIKE LEFT(@DT, 6) + '%'; --DT컬럼이 int형 YYYYMMDD형식일 경우 SELECT ColA, ColB, ColC FROM TableA WHERE DT BETWEEN LEFT(@DT, 6) + '01' AND CONVERT(char(8), DATEADD(mm, 1, LEFT(@DT, 6) + '01') - 1, 112); }}} 보나마다 datetime, smalldatetime은 더 짜증이다. ==== SQL Server 날짜 데이터 형식과 초단위 처리 ==== SQL Server 2005이하 버전의 경우 다음의 2가지 날짜 데이터형식을 가진다. * smalldatetime * datetime smalldatetime은 4byte의 고정길이이며, 분 단위까지 표현가능하다. datetime은 경우 8byte 고정길이이며, 밀리초 단위까지 표현가능하다. 하지만 밀리초 단위 이하까지 필요한 업무는 그리 많지 않다. 그러므로 초 단위까지만 표현할 수 있는 데이터형식이 필요한다. SQL Server의 경우는 지원하지 않는다. 그래서 Unix에서 처럼 날짜를 초단위까지 표현하는 방법을 커닝하여 int형 byte로 줄여서 저장하는 것이다. (SAS 날짜 데이터형식의 경우는 8byte 숫자형으로 1960-01-01을 표현하더라) {{{ select dateadd(s, 2147483647, '20090101') --2009-01-01부터라면 2077-01-19 03:14:07.000까지 표현가능 select datediff(s, '20090101', '2077-01-19 03:14:07.000') --역변환, 2147483647 select datediff(s, '20090101', getdate()) --오늘 25899270 }}} 데이터베이스의 성능의 기본은 저장공간을 줄이는 것이다. 그리고 요즘은 CPU가 워낙 좋아서 CPU를 잘 써먹는 방법도 연구해 보아야 한다. 옛날 같으면 이와 같은 연산이 부담스러울수도 있으나, 현재의 경우는 아주 부담이 적다. CPU에 약간의 부하를 주고, Row당 4byte의 이득을 보는 것이 더 나은 선택이 아닌가 싶다. ==== date 형 ==== sql server 2008 버전부터 date 형이 생겼다. 3byte다. 좋쿠만.