MySQL 타입비교 - datetime vs. timestamp

    날짜와 시간을 표현하는 데이터타입

    MySQL에서 YYYY-MM-DD HH:MM:SS (년-월-일 시:분:초)로 날짜를 표현하는데 사용되는 데이터 타입으로, datetime과 timestamp 두 가지가 있다. 기본적으로 시간을 표현한다는 점에서는 유사해 보이지만, 저장되는 값의 형태와 동작하는 방식의 차이점, 그리고 제약사항을 인지하고 사용해야 한다.


    DATETIME과 TIMESTAMP 비교

    시간 정보를 DATETIME과 TIMESTAMP로 표현할 때 어떤 차이가 있는지 살펴보자.


    DATETIME

    • 표현가능 범위: 1000-01-01 00:00:00~9999 - 12:31 23:59:59

    타임존에 대한 변환 없이, 저장할 때 값 그대로 저장이 된다. 타임존 설정에 영향을 받지 않으므로, 미국 시간대로 저장된 값을 한국에서 읽어와도 그 타임스탬프가 그대로 유지된다.


    TIMESTAMP

    • 표현가능 범위: 1970-01-01 00:00:01 - 2038-01-19 03:14:07

    1970-01-01 00;00:00 (UTC)로부터 흐른 시간을 초로 환산하여 저장한다. TIMESTAMP로 지정된 컬럼은 값이 저장될 때, UTC 기준 현재 DB세션의 타임존으로 환산하여 저장하고, 읽어들일 때 마찬가지로 현재 세션의 타임존을 참고하여 읽어들인다. 저장할 때, 타임존 ID를 별도로 저장하는 것은 아니다. DATETIME과 비교하자면, 미국 시간대로 기록한 시간대를 TIMESTAMP 형으로 기록하면, 한국에서 읽어들이면 한국시간으로 변환된다.


    동작 비교

    같은 값을 DATETIME, TIMESTAMP로 환산하면 어떻게 동작하는지 다음의 예로 확인해 보자.

    create table date_test (
        id int auto_increment,
        createdAsDatetime datetime,
        createdAsTimestamp timestamp,
        description varchar(64),
        primary key (id)
    );

    위와 같이 테스트를 위한 간단한 스키마를 만든다. 한 컬럼은 DATETIME으로, 다른 컬럼은 TIMESTAMP로 만들고 같은 시간을 저장하고 지역에 따라, 즉 타임존에 따라 값이 어떻게 달라지는지 살펴보자. 미국에 있는 상황을 가정하기 위해, 다음과 같이 설정한다.

    mysql> set @@session.time_zone = 'America/Los_Angeles';
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> select @@global.time_zone, @@session.time_zone;
    +--------------------+---------------------+
    | @@global.time_zone | @@session.time_zone |
    +--------------------+---------------------+
    | SYSTEM             | America/Los_Angeles |
    +--------------------+---------------------+
    1 row in set (0.00 sec)

    위와 같이 변경한 후, 현재 시간을 조회해 보면 미국의 시간으로 조회가 되는 것을 확인할 수 있다.

    mysql> select now();
    +---------------------+
    | now()               |
    +---------------------+
    | 2021-05-16 08:15:38 |
    +---------------------+
    1 row in set (0.02 sec)

    이제 위에서 만든 테이블에 값을 저장해 보자. 미국에서 저장한 시간 값이 어떻게 달라지는지 보고자 한다.

    mysql> insert into date_test(createdAsDatetime, createdAsTimestamp, description) values(now(), now(), 'inserted in US/LA');
    Query OK, 1 row affected (0.02 sec)

    이제 위 테이블의 결과를 그대로 조회를 해보면, 즉 미국에서 데이터를 저장하고 미국에서 데이터를 읽는 경우니까 별 차이가 없을 것이다.

    mysql> select * from date_test;
    +----+---------------------+---------------------+-------------------+
    | id | createdAsDatetime   | createdAsTimestamp  | description       |
    +----+---------------------+---------------------+-------------------+
    |  1 | 2021-05-16 08:17:53 | 2021-05-16 08:17:53 | inserted in US/LA |
    +----+---------------------+---------------------+-------------------+
    1 row in set (0.04 sec)

    그런데, 한국에 있는 개발팀이 혹은 한국의 서비스가 이 테이블을 액세스하면 어떻게 될까? 한국의 상황을 가정해야 하므로, 타임존의 설정을 한국으로 변경하고 위의 데이터를 다시 조회해 보자. (혹은 새 세션으로 접속하면, 시스템 설정을 따를 것이므로 한국으로 붙을 것이다. 단, 한국 환경으로 되어 있다면)

    mysql> select @@global.time_zone, @@session.time_zone;
    +--------------------+---------------------+
    | @@global.time_zone | @@session.time_zone |
    +--------------------+---------------------+
    | SYSTEM             | +08:00              |
    +--------------------+---------------------+
    1 row in set (0.00 sec)

    이제 데이터를 조회해 보면, 아래와 같다.

    mysql> select * from date_test;
    +----+---------------------+---------------------+-------------------+
    | id | createdAsDatetime   | createdAsTimestamp  | description       |
    +----+---------------------+---------------------+-------------------+
    |  1 | 2021-05-16 08:17:53 | 2021-05-16 23:17:53 | inserted in US/LA |
    +----+---------------------+---------------------+-------------------+
    1 row in set (0.04 sec)

    위의 테스트 결과에서 보다시피, datetime 컬럼은 입력할 당시의 값이 그대로 노출되는 반면, timestamp 컬럼은 현재의 타임존 설정에 따라 자동으로 변경되어 노출된다.

    댓글(0)

    Designed by JB FACTORY