来自客户端或服务器的时间戳-最佳做法是什么?

时间:2019-06-10 17:35:18

标签: java mysql

我有一个Java应用程序,它将一些数据插入到我的mysql数据库中。到目前为止,我已经通过Java代码从客户端计算机获取了时间戳:

DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date insertDate= new Date();

,然后在我准备好的语句中使用它,例如

update 'table'set (status,insertDate) values (?,?)
pst.setString(1, "Success");
pst.setString(2, dateFormat.format(insertDate)); 

这工作正常,但是如果其中一个客户端弄乱了系统时间并将其设置为一天,那该怎么办?因此,我想将服务器的时间戳记作为基本事实(发生插入操作的实际时间),发现我可以使用NOW()了。我更改了代码,现在看起来像这样

update 'table' set (status,insertDate) values (?,NOW())
pst.setString(1, "Success");

这是完成这项工作的正确方法吗?我假设这将插入请求到达服务器并发生插入时的时间戳,而不是直接从客户端获取timstamp。我的理解正确吗?

1 个答案:

答案 0 :(得分:0)

转到服务器端

如果要在插入数据库时​​捕获当前时刻,最好的方法当然是在服务器上捕获该时刻。您可以比最终用户更信任服务器系统管理员,以保持计算机时钟的正确设置。

提示:通常,最好将可以将所有工作从应用程序移至数据库服务器,如果您具有功能强大的强大数据库服务器。

DEFAULT CURRENT_TIMESTAMP

更好,自动化。无需始终将current-moment-capture写入SQL事务代码中。

相反,应在服务器上定义一个DEFAULT值,作为定义表和列的一部分。

根据this doc,函数 CURRENT_TIMESTAMP是标准SQL ,用于捕获从服务器时钟读取的当前事务开始时的当前时刻。我不知道使用标准SQL命令来捕获语句执行期间的当前时刻(与事务开始相反)。

当前时刻应存储在类似于标准SQL类型TIMESTAMP WITH TIME ZONE的数据类型的列中。

此代码可能与标准SQL相似,并且可以在诸如Postgres之类的数据库中使用。

CREATE TABLE Person (
    pkey_ INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    surname_ VARCHAR(80) NOT NULL ,
    given_name_ VARCHAR(80) NOT NULL ,
    row_inserted_ TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP 
) ;

关于MySQL:

  • 显然在MySQL 8中,类型TIMESTAMP WITH TIME ZONETIMESTAMP
  • 我收集到MySQL尚不支持标准的GENERATED…功能,因此请使用AUTO_INCREMENT
  • This doc说MySQL 8支持标准函数名CURRENT_TIMESTAMP。这是Question代码中特定于MySQL的NOW()函数的同义词。我建议在可行的情况下都遵守标准。

(我不使用MySQL,因此请验证详细信息。)

MySQL示例:

CREATE TABLE Person (
    pkey_ INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    surname_ VARCHAR(80) NOT NULL ,
    given_name_ VARCHAR(80) NOT NULL ,
    row_inserted_ TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP 
) ;

将自动插入的值作为OffsetDateTime对象检索。

OffsetDateTime odt = myResultSet.get( "row_inserted_" , OffsetDateTime.class ) ;

看到那一刻是在特定地区(时区)的人们使用的挂钟时间而不是UTC中看到的。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = odt.withZoneSameInstant( z ) ;

enter image description here