Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL UPDATE에서 datetime = NOW() 사용 시 모든 행이 동일한 날짜/시간을 갖는 이유

MySQL에서 UPDATE 문에 NOW() 함수를 사용해 datetime 컬럼을 갱신하면, 업데이트된 모든 행은 동일한 날짜/시간 값을 갖게 됩니다. 그 이유는 NOW()가 쿼리(문장)가 실행되기 시작한 시점의 시간을 상수처럼 반환하기 때문입니다.

반면 SYSDATE() 함수는 MySQL 5.0.13부터 해당 함수가 실제로 실행되는 정확한 시각을 반환합니다. 즉, 트리거나 저장 프로시저 안에서 NOW()로 datetime을 갱신하는 경우, 트리거나 저장 프로시저가 실행을 시작한 시점의 시간이 반환됩니다.

실습 예제: 테이블 생성

NOW()를 사용한 UPDATE의 동작을 확인하기 위해 먼저 데모용 테이블을 생성해 보겠습니다. 테이블 생성 쿼리는 다음과 같습니다.

mysql> create table NowDemo
-> (
-> DueDateTime datetime
-> );
Query OK, 0 rows affected (0.51 sec)

데이터 삽입

INSERT 명령으로 테이블에 레코드를 추가합니다.

mysql> insert into NowDemo values('2018-12-19');
Query OK, 1 row affected (0.15 sec)

mysql> insert into NowDemo values('2018-11-10');
Query OK, 1 row affected (0.20 sec)

mysql> insert into NowDemo values('2017-11-21');
Query OK, 1 row affected (0.09 sec)

저장된 데이터 확인

SELECT 문으로 테이블의 모든 레코드를 조회합니다.

mysql> select *from NowDemo;

실행 결과:

+---------------------+
| DueDateTime |
+---------------------+
| 2018-12-19 00:00:00 |
| 2018-11-10 00:00:00 |
| 2017-11-21 00:00:00 |
+---------------------+
3 rows in set (0.00 sec)

Case 1 − NOW() 사용

datetime 컬럼을 NOW()로 갱신하는 쿼리입니다. 모든 행의 값이 한 번에 업데이트됩니다.

mysql> update NowDemo set DueDateTime = now();
Query OK, 3 rows affected (0.12 sec)
Rows matched: 3 Changed: 3 Warnings: 0

SELECT 명령으로 갱신된 값을 확인합니다.

mysql> select *from NowDemo;

아래 출력 결과에서 볼 수 있듯이, 모든 행이 동일한 날짜/시간(문장 시작 시각)으로 갱신되었습니다.

+---------------------+
| DueDateTime |
+---------------------+
| 2018-12-20 16:10:00 |
| 2018-12-20 16:10:00 |
| 2018-12-20 16:10:00 |
+---------------------+
3 rows in set (0.00 sec)

Case 2 − SYSDATE() 사용

이번에는 SYSDATE()로 갱신하는 쿼리입니다.

mysql> update NowDemo set DueDateTime = sysdate();
Query OK, 3 rows affected (0.43 sec)
Rows matched: 3 Changed: 3 Warnings: 0

SELECT 문으로 테이블의 갱신된 값을 확인합니다.

mysql> select *from NowDemo;

출력 결과:

+---------------------+
| DueDateTime |
+---------------------+
| 2018-12-20 16:10:35 |
| 2018-12-20 16:10:35 |
| 2018-12-20 16:10:35 |
+---------------------+
3 rows in set (0.00 sec)

정리

NOW()는 문장이 시작된 시점의 시간을 고정적으로 반환하므로, 하나의 UPDATE 문으로 여러 행을 갱신하더라도 모든 행이 같은 날짜/시간 값을 갖습니다. 반면 SYSDATE()는 행마다 실제 실행 시각을 평가하므로, 문장 실행이 오래 걸리면 행별로 값이 달라질 수 있습니다. 위 예제에서는 실행 속도가 매우 빨라 세 행 모두 같은 값으로 표시되었습니다. 따라서 일괄 갱신 시 모든 행에 동일한 타임스탬프를 보장하려면 NOW()(또는 CURRENT_TIMESTAMP)를 사용하는 것이 안전합니다.