如何在MySQL中最佳存储日期/时间?

3

我应该存储一个Delphi TDateTime,还是先转换为Unix时间戳?或者直接作为字符串存储?

在MySql中,我应该如何声明这一列?作为Double、DateTime(如果使用Unix时间戳则为Integer)?

什么是“正确”的做法,或者如果我想要显示一个带有“yyyy mm dd hh:mm:ss”(或类似的)字符串,并能够比较两个值之间的经过时间,最简单的方式是什么?

顺便说一句,程序将永远只在一个不使用夏令时的时区中使用。

我很困惑,似乎无法在任何地方找到相关讨论。有什么有用的链接吗?


3
视您是否打算存储时区而定。 - njzk2
+1个问题已更新。谢谢,@njzk2 - Mawg says reinstate Monica
6个回答

9
  1. Should I be storing a Delphi TDateTIme, or perhaps convert to Unix timestamp first?

    Typically, you should do neither: the data types in the database layer ought to be meaningful (as possible) on their own and not depend on your application to interpret them. As @Jim DeLaHunt says, this enables the database to easily manipulate/interpret them from SQL as required (and also enables you to easily access the same data from another application codebase in the future).

    MySQL has five temporal types, only two of which store both a date and a time: DATETIME and TIMESTAMP.

    As others have alluded, the difference comes down to whether you wish to store the timezone - although I find that quite a confusing way of looking at it:

    • TIMESTAMP uses the session's time_zone variable to convert input into a UTC timestamp and then back again for output: it's useful for specifying an exact moment in time;

    • DATETIME simply stores the date and time without regard to timezone, much like taking a photograph of a calendar and clock: it's useful for specifying an event that occurs in the same local time globally.

  2. How should I declare the column in MySql? As a Double, or DateTime (or Integer if I use Unix timestamp)?

    Just as you would declare any other column, you specify the relevant data type after the column name.

    Beware that TIMESTAMP has additional features, such as automatic update, which you may wish to disable in your column declaration if so desired.

  3. Whta is "correct", or what is easiest if I want to be able to display a string with "yyyy mm dd hh:mm:ss" (or similar) and also to be able to get an elapsed time from comparing two values?

    Using one of the above temporal types, you will be able to do all of this (using date functions as required). The default output of TIMESTAMP and DATETIME types is a string in 'YYYY-MM-DD HH:MM:SS' format.

    In particular, the "elapsed time" from comparing two values could for example be obtained with MySQL's TIMEDIFF() function:

    SELECT TIMEDIFF(end, start) AS elapsed
    FROM   my_table
    WHERE  ...
    

4

MySQL应该具有本地日期格式,这是首选的,因为它允许使用SQL日期函数(年、月等)。

我在其中一个数据库表中定义了一个字段,它被定义为Delphi datetime - 回顾起来,这是一个错误,因为在该字段上进行筛选或显示值非常困难。这两个操作需要在调用程序中进行特殊处理,而不是在数据库中进行。


2

1

这个链接可能对你有用。这取决于你是否想使用时区,但即使现在不需要它们,也要重新考虑一下是否将来可能需要使用它们。

我会使用DATETIME。它更容易被人类阅读。


1

您可以在MySQL参考手册,11.3.日期和时间类型中了解有关MySQL日期和时间类型的所有信息,并在12.7.日期和时间函数中了解有关函数的信息。

我的经验是,在MySQL和SQL Server中,虽然不是针对Delphi,但最好将日期和时间值存储在数据库的日期和时间格式中。这样,您可以使用数据库的日期和时间函数,并利用其优化的日期和时间功能实现。如果将datetime值存储为通用类型,例如Double或Integer Unix时间戳,则会缺少优化,并且必须实现自己的等效日期和时间函数。

根据OP编辑后的问题进行更新:

DateFormat()函数可以使用格式字符串"%Y %m %d %k:%i:%s",给出类似于"yyyy mm dd hh:mm:ss"的字符串。

TimeDiff()函数将返回一个时间间隔类型,表示两个日期时间值之间的差异。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接