繁体   English   中英

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

[英]Timestamp from the client or the server - What's the best practice?

我有一个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。 我的理解正确吗?

进入服务器端

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

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

DEFAULT CURRENT_TIMESTAMP

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

而是在服务器上定义DEFAULT值,作为定义表和列的一部分。

根据该文档 ,函数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 ZONE将是TIMESTAMP
  • 我发现MySQL还不支持标准的GENERATED…功能,因此请使用AUTO_INCREMENT
  • 该文档说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 ) ;

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM