您是否建议使用datetime或timestamp字段,以及为什么(使用mysql)?
我正在服务器端使用PHP。
- 这有一些相关信息codeproject.com/tips/1215635/mysql-datetime-vs-timestamp
MySQL中的时间戳通常用于跟踪对记录的更改,并且经常在每次更改记录时更新。如果要存储特定值,则应使用日期时间字段。
如果您想决定使用unix时间戳还是本机mysql日期时间字段,请使用本机格式。你可以用这种方式在MySQL中进行计算("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")并且在查询记录时,如果要使用php对其进行操作,很容易将值的格式更改为unix时间戳("SELECT UNIX_TIMESTAMP(my_datetime)")。
- 一个重要的区别是,DATETIME表示日期(如日历中所示)和时间(如挂钟上所示),而TIMESTAMP表示定义良好的时间点。如果应用程序处理时区,这可能非常重要。"2010-09-01 16:31:00"多久以前?这取决于你在哪个时区。对我来说,这只是几秒钟前的事,对你来说,这可能代表着未来的一段时间。如果我说从1970-01-01 00:00:00 UTC开始的1283351460秒,你知道我说的是什么时间点。(参见下面NIR的最佳答案)。[缺点:有效范围]。
- 另一个区别是:具有"本机"日期时间的查询不会被缓存,但是具有时间戳-的查询将被缓存。
- "MySQL中的时间戳通常用于跟踪记录的更改"不认为这是一个好的答案。时间戳比MattBianco和Nir Sayd所说的更强大和复杂。尽管如此,第二部分的答案还是很好的。布莱维特说的是真的,这是一个很好的建议。
- "每次更改记录时都会更新"是真的吗?每次更改行时,时间戳字段都会自动更新为当前时间?
- 还有一个重要的注意事项,date time和timestamp可以使用当前的timestamp,now()作为它的默认值,但是date不能使用,因为它默认使用"0000-00-00",所以为了解决这个问题,u应该将自己的触发器写入该表,将当前日期(没有时间)插入到日期mysql类型的字段/col中。
- 作为对@zeusakm的响应,有一个限制,即每个表只能有一个时间戳列具有默认的当前时间戳设置。
- 是的,这是一句中肯的话,这个特点逻辑上是公平的,不需要别人。
- @chaigoy-我在文档中找不到对此的引用,使用MySQL5.5测试表明,当我更新一行时,TIMESTAMP列没有更改。
- @davidharkness:documentation说"要指定自动属性,请使用默认的当前时间戳和更新当前时间戳子句"dev.mysql.com/doc/refman/5.0/en/timestamp initialization.htm‌&8203;l
- @Oz_uu:当然,带有静态日期时间值的查询将被MySQL缓存。不缓存涉及NOW()、CURDATE()和类似功能的查询。您可以缓存所有查询,这些查询只包含每次为同一参数返回相同值的函数。
- "如果您想决定使用UNIX时间戳还是本机MySQL日期时间字段,请使用本机格式。"—为什么?请参阅billauer.co.il/blog/2009/03/mysql-datetime-epoch-unix-time了解不同的意见。
- 时间戳:固定的时间点,协调的世界时间。日期时间:相对于一个视角,对于像时区本地时间这样的时间引用,可以是..协调当地时间?
- @奥兹,我把你的评论作为答案。如果你可以扩展它或发表你自己的答案与链接到你的参考资料,那将是伟大的。
- 或者@marki555,如果您引用了datetime与timestamp的缓存行为,那也太好了。
- @nobleuplift dev.mysql.com/doc/refman/5.5/en/query-cache-operation.html-从大约一半的文本开始,有查询缓存不支持的函数列表以及一些其他限制,并解释如何比较查询…
- @Zeusakm,如这里所说stackoverflow.com/questions/23153822/…,mysql 5.6中添加了DEFAULT CURRENT_TIMESTAMP对EDOCX1(数据类型)的支持。
- 不能使用NULL为DATETIME字段设置DEFAULT_TIMESTAMP。
- 对我来说,这取决于你的情况。如果我更新了列,我将设置为使用时间戳。当删除并创建时,我使用日期时间
在MySQL5及以上版本中,时间戳值从当前时区转换为用于存储的UTC,然后从UTC转换回当前时区进行检索。(这仅适用于timestamp数据类型,而不适用于其他类型,如datetime。)
默认情况下,每个连接的当前时区是服务器的时间。可以根据每个连接设置时区,如mysql服务器时区支持中所述。
- 来源:dev.mysql.com/doc/refman/5.1/en/datetime.html
- 这个Oreilly演示非常适合这个主题(pdf抱歉)cdn.oreillystatic.com/en/assets/1/event/36/…
- 它还涉及事件的性质:视频会议(时间戳)。所有的服务员都应该看到一个时间的绝对瞬间的参考值,并根据它的时区进行调整。-作为一个本地任务时间(日期时间),我应该在2014/03/31 9:00完成这项任务。如果那天我在纽约或巴黎工作,那没关系。我将在当地时间上午8:00开始工作,我将在当天工作。
- 因此,如果我更改服务器的时区,那么时间戳的值将保持不变,还是也会更改??
- @安德鲁既然是UTC,它将保持UTC。但是,反向转换将更改为"新"服务器时区。
除了行元数据(创建或修改日期),我总是使用日期时间字段。
如MySQL文档中所述:
The DATETIME type is used when you need values that contain both date and time information. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.
...
The TIMESTAMP data type has a range of '1970-01-01 00:00:01' UTC to '2038-01-09 03:14:07' UTC. It has varying properties, depending on the MySQL version and the SQL mode the server is running in.
在一般情况下,您很可能会达到时间戳的下限——例如存储生日。
- 如果你在银行或房地产行业,你也可以很容易地达到上限…30年期抵押贷款现在超过2038年
- 当然,使用64位UNIX时间戳。例如,在Java中,EDCOX1(5)已经给了您一个64位的值。
- +1对于日期时间:在我们的数据流中,从用于购买和发票的物理存储的SQL Server传输到网页上的虚拟存储的MySQL Server,由于此数据类型也存在于Transact-SQL中,因此日期时间更适合于修改日期时间。但时间戳在Transact-SQL中意味着另一件事,它与rowversion类似,尽管mysql时间戳与datetime类似。因此,我们避免使用时间戳来实现两个DBS的兼容性。
- @斯克鲁尼德,2038年是接近每一年。他们(mysql)计划扩展范围吗?
- 不知道。这是一个比MySQL更大的问题,没有简单的解决方法:en.wikipedia.org/wiki/year__problem我不相信MySQL可以声明时间戳现在是64位的,并且假设一切都会好起来。他们不控制硬件。
- 不相关的例子:生日是日期,而不是日期时间。无论如何,出生是附属于一个地方,所以当事件发生时,它附属于一个特定的时区。但是日期时间没有这个信息。时间戳是一个特定的时间瞬间,您可以将其转换为任何时区(用于显示),从而保留核心信息。
- 如果你知道出生时间,生日可以是一个日期时间,就像我对我的时间一样。
- 使用时间戳的下限出生日期风险是否真实?我们在google bigquery中有数据,时间戳字段的生日值可以追溯到19世纪。
- @Praxiteles这是关于MySQL的。BigQuery是它自己的系统,对其数据类型有自己的限制。例如,它支持Unix时代之前日期的负时间戳。
- @kip——对于抵押贷款,只需要DATE。范围是0000到9999年。
- @scronide它们不需要控制硬件,64位数字在32位系统上可以正常工作,只需要几个额外的CPU周期就可以对它们进行计算。
下面的示例显示了在DATETIME不变的情况下,TIMESTAMP日期类型在更改time-zone to 'america/new_york'之后如何更改值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| mysql > show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name | Value |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone | Asia /Calcutta |
+------------------+---------------------+
mysql > create table datedemo (
-> mydatetime datetime,
-> mytimestamp timestamp
-> );
mysql > insert into datedemo values ((now()),(now()));
mysql > select * from datedemo ;
+---------------------+---------------------+
| mydatetime | mytimestamp |
+---------------------+---------------------+
| 2011-08-21 14: 11: 09 | 2011-08-21 14: 11: 09 |
+---------------------+---------------------+
mysql > set time_zone ="america/new_york";
mysql > select * from datedemo ;
+---------------------+---------------------+
| mydatetime | mytimestamp |
+---------------------+---------------------+
| 2011-08-21 14: 11: 09 | 2011-08-21 04: 41: 09 |
+---------------------+---------------------+ |
我已经将我的答案转换成了一篇文章,这样更多的人可以发现这个有用的,mysql:datetime和timestamp数据类型。
- 实际上,随着时区的变化,DATETIME的有效时间也发生了变化,TIMESTAMP没有改变,但人类的代表性改变了。
- 似乎这个命令在MySQL5.6set time_zone="america/new_york"中不起作用;
- 这里是设置时区问题的答案。stackoverflow.com/questions/3451847/mysql-timezone-change
- 同意@Flindeberg。时间戳表示时区更改后的正确时间,而不是日期时间。
主要区别在于datetime是常量,而timestamp受time_zone设置的影响。
因此,只有当您已经或将来可能已经跨时区同步集群时,这才重要。
简单来说:如果我在澳大利亚有一个数据库,并转储该数据库以在美国同步/填充数据库,那么时间戳将更新以反映新时区中事件的实时性,而日期时间则仍然反映AU时区中事件的时间。
在Facebook中,使用时间戳的一个很好的例子就是使用日期时间戳,在Facebook中,他们的服务器永远无法确定跨时区发生了什么时间事件。有一次,我正在进行一次谈话,在谈话中,时间说我是在回复消息之前才真正发送消息。(当然,如果发布时间而不是同步时间,这也可能是由于消息传递软件中的时区转换错误造成的。)
- 我认为这不是一种好的思考方式。我只需要存储和处理所有的日期在UTC,并确保前端显示它根据给定的时区。这种方法简单且可预测。
- @科斯:在UTC中存储和处理所有日期,难道不是时间戳在内部的作用吗?(然后将其转换为显示本地时区?)
- 我的本地时区?你的数据库怎么知道我的时区?;-)通常在数据库和用户界面之间有相当多的处理。我只在整个处理之后才进行本地化。
- @我的数据库不知道你的数据库时区:!但它知道时间戳。您的数据库知道自己的时区设置,并在解释/表示时间戳时应用该设置。2013年12月11日上午1:01在中国北京的时间与2013年12月11日上午1:01在澳大利亚悉尼的时间不同。谷歌:"时区"和"本初子午线"。
- 区别不仅仅在于集群中其他服务器的时区。相关的设置是在来自任何MySQL客户机的连接中定义的时区(默认情况下与服务器相同,但您的默认值可能取决于客户端驱动程序)。
- MySQL将时间戳值从当前时区转换为用于存储的UTC,然后从UTC转换回用于检索的当前时区。(对于其他类型,如datetime,不会发生这种情况。)dev.mysql.com/doc/refman/5.5/en/datetime.html
我是在语义基础上做出这个决定的。
当需要记录(或多或少)固定时间点时,我使用时间戳。例如,当一条记录被插入到数据库中或发生了某个用户操作时。
当日期/时间可以任意设置和更改时,我使用日期时间字段。例如,当用户可以保存以后更改的约会时。
- 时间戳-固定的时间点,协调的通用时间日期时间-相对于一个观点,到一个时间引用(EJ时区本地时间)可能是..协调当地时间?
我建议既不要使用日期时间字段也不要使用时间戳字段。如果你想代表一个特定的一天作为一个整体(比如生日),那么使用日期类型,但是如果你比这更具体,你可能会有兴趣记录一个实际的时刻,而不是一个时间单位(天、周、月、年)。使用DigeTimes或时间戳,而不是使用BigIt,只需存储EPOCH(System .CurrnTimeMILISH())中的毫秒数,如果您使用Java)。这有几个优点:
避免供应商锁定。几乎每个数据库都以相对相似的方式支持整数。假设您想移动到另一个数据库。是否要担心MySQL的日期时间值之间的差异以及Oracle如何定义它们?即使在不同版本的MySQL中,时间戳的精度也不同。仅在最近,MySQL才支持时间戳中的毫秒数。
没有时区问题。对于不同数据类型的时区,这里有一些有见地的评论。但这是常识吗?你的同事会花时间学习吗?另一方面,很难把bigint改成java.util.date。使用bigint会导致很多时区问题的发生。
无需担心范围或精度。您不必担心未来日期范围会缩短哪些时间(时间戳仅限于2038)。
第三方工具集成。通过使用整数,第三方工具(例如EclipseLink)与数据库进行交互非常简单。并不是每一个第三方工具都能像MySQL那样理解"日期时间"。想要在Hibernate中尝试找出是否应该使用java.sql.timestamp或java.util.date对象(如果使用这些自定义数据类型)?使用基本数据类型使得与第三方工具的使用变得简单。
这个问题与如何在数据库中存储货币值(即1.99美元)密切相关。您应该使用十进制,还是数据库的货币类型,或者最糟糕的是使用双精度?所有3个选项都很糟糕,原因与上面列出的许多相同。解决方案是使用bigint将货币值存储为美分,然后在向用户显示值时将美分转换为美元。数据库的工作是存储数据,而不是重复这些数据。您在数据库(尤其是Oracle)中看到的所有这些花哨的数据类型都没有增加什么,这会让您踏上供应商锁定的道路。
- 我喜欢这个解决方案。2038年到期的时间戳是一个主要问题。那真的不远!
- @你认为现在的软件会在那时出现吗?
- 我的时间戳有问题。这种重大的选择似乎更好。
- 我也选择了bigint。储藏室很便宜。前端创建您想要的任何日期符号。查询范围没有问题(需要一天,查询一个范围)。非常兼容任何系统。
- 如果数据以毫秒为单位存储,则很难按日期查询数据
- 如果您关心可移植性并在多个时区处理用户,或者在不同时区处理数据库,那么这确实是最好的解决方案。如果没有设计缺陷,时间戳可能是解决问题的方法。糟糕的是,坏的解决方案得到了更多的选票,因为它们被提前发布(几年!).
- 毫无疑问,这是最好的解决方案——但我建议以秒为单位存储,而不是以毫秒为单位。在这两种情况下:没有时区问题,没有未来的问题,它是相对于服务器/数据的绝对值,但是可以很容易地进行本地化。另一种类似的方法是将iso日期/时间存储为varchar,但使用bigint会消耗较少的空间并使日期/时间数学变得简单。
- 很好的解决方案!你完全正确,不要被"锁在里面"。当你养成了让别人"为你做工作"的习惯,你就会开始失去那些让你成为程序员的零碎东西。
- 这个解决方案使开发成为一个噩梦。当你查看你的原始数据库数据时,你会得到荒谬的整数。
- @你能详细描述一下这个荒谬的地方吗?有序整数是如何成为噩梦的?对于日期间隔,BETWEEN也有效…如果需要检查特定的日期,可以使用侧/客户端服务器语言进行转换,也可以使用在线服务(例如epochconverter)。
- 谢谢你的评论。问题是,如果您需要检查特定的日期,您必须使用侧面/客户机-服务器语言来转换,或者使用在线服务。显然,使用传统格式输入目标日期的效率较低。由于某种原因,termoporal数据类型在RDBMS中。
- @使用秒而不是毫秒的亚赫尔曼至少会损失两(三?)个精度。数量级。(如果在同一秒内发生多个事件,则不能保证时间戳是唯一的。因此,时间戳不能用作主键,需要一个额外的AUTOINCREMENT列作为pk。)当然,如果时间关键代码需要以微秒或纳秒为单位的精度,这也是正确的。
时间戳是4个字节,而datetime是8个字节。
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
但正如斯克里德所说,它确实有一个1970年的下限。不过,它对将来可能发生的任何事情都很有帮助;)
- 未来将在2038-01-19 03:14:07 UTC结束。
- 那太愚蠢了。我认为时间戳类型将是"未来就绪"的,因为它相对较新。当您处理不同时区时,您不必每次都将日期时间转换为UTC和向后转换。他们应该把时间戳变大。至少大1字节。再加上68*255=17340年…虽然它不会被32位对齐。
- 你知道为什么时间戳在2038年结束吗?因为它是一个整数,整数的极限是2147483647。我想这就是原因。如果他们把它的类型改为varchar并改变如何操作它,它将是"未来准备好的"。
- @维萨,我想到那时它还没准备好。还记得千年虫吗?2038来了。
- 到2038年,MySQL(如果它仍然存在的话)将简单地更新timestamp字段,使其使用超过4个字节,并允许更大的范围
时间戳是4个字节,而datetime是8个字节。
数据库中的时间戳也更轻,索引速度更快。
当需要同时包含日期和时间信息的值时,将使用日期时间类型。MySQL检索并以"yyyy-mm-dd hh:mm:ss"格式显示日期时间值。支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。
时间戳数据类型的范围是'1970-01-01 00:00:01'UTC到'2038-01-09 03:14:07'UTC。它有不同的属性,这取决于MySQL版本和服务器运行的SQL模式。
日期时间是常量,而时间戳受时区设置的影响。
- 您需要澄清4:存储的时间戳是常量,与时区不相关(完全不可知),而检索时显示的输出受请求会话时区的影响。日期时间总是与它所记录的时区相关的,并且必须始终在该上下文中考虑它,这一责任现在落在应用程序身上。
- 很好的回答。为了增加这个答案,如果我们试图存储超过"2038-01-09 03:14:07"的值,我们要么得到一个错误,要么它被存储为"0000-00-00 00:00:00"。我的数据库出现此错误,因为它有时间限制值(用于加密)。
- 另外,在5.5以下的MySQL版本上,datetime的默认值存在问题。dba.stackexchange.com/questions/132951/…
这真的取决于应用程序。
考虑将用户的时间戳设置为在纽约的服务器,以便在Sanghai预约。现在,当用户连接到三海时,他从东京的镜像服务器访问相同的约会时间戳。他将在东京时间看到任命,与原来的纽约时间相抵。
因此,对于表示用户时间(如约会或日程)的值,datetime更好。它允许用户控制所需的确切日期和时间,而不管服务器设置如何。设置时间是设置的时间,不受服务器时区、用户时区或夏令时计算方式的更改(是的,它确实会更改)的影响。
另一方面,对于表示系统时间的值(如付款事务、表修改或日志记录),始终使用时间戳。将服务器移动到其他时区或在不同时区的服务器之间进行比较时,系统不会受到影响。
数据库中的时间戳也更轻,索引速度更快。
2016+:我建议您将MySQL时区设置为UTC并使用日期时间:
任何最新的前端框架(Angular 1/2、React、Vue等)都可以轻松自动地将您的UTC日期时间转换为本地时间。
另外:
- 现在可以自动将datetime设置为当前时间值。如何为mysql datetime列设置默认值?
- 与人们想象的相反,日期时间比时间戳快,http://gpshumano.blogs.dri.pt/2009/07/06/mysql-datetime-vs-timestamp-vs-int-performance-and-benchmarking-with-myisam/
- 时间戳仍限于1970-2038年
(除非您可能更改服务器的时区)
AngularJS示例
此处提供的所有本地化时间格式:https://docs.angularjs.org/api/ng/filter/日期
- 您的数据不应附加到服务器的时区设置。也许,如果你桌子下面有一个mysql盒子,它对你有用。
- @jin-utc表示没有时间戳这样的时区。如果您的所有服务器都是UTC格式,那么就没有问题。如果你有一个2000的配置,它可能对你不起作用。
- 将来时间戳可能升级为64位值。那就没问题了。
- 加载整个第三方库以捕获类似的内容,这对性能也不太好,对吧?因为它是客户端的,不影响数据库…不过,您所做的任何前端操作都需要服务器端检查。所以,考虑到整个画面,它真的有助于解决速度问题吗?--我觉得这些基准有点奇怪。在查询中使用一个字符串来比较时间戳字段也感觉很奇怪。这也会损害性能,对吗?
- @BabyDead显然,您不会仅仅为了转换日期而加载库,但是使用前端框架对于现代的、干净的代码来说是一个很好的实践。
- 嗯,我只是想说,由于第三方解决方案,假设任何标准都是不好的。我不打算开始讨论使用这样的框架是否是好的实践(我不同意)。我的观点是讨论什么是最好的PHP以及为什么。添加第三方插件会改变所有游戏和视角。这可能会成为一场无休止的辩论。
- @BabyDead无论如何,即使您不想使用框架,将UTC时间转换为本地时间也比一般情况下两个不同时区之间的转换要简单。
timestamp字段是datetime字段的特例。您可以创建timestamp列以具有特殊属性;可以将其设置为在创建和/或更新时更新自身。
在"更大"的数据库术语中,timestamp有几个特殊的案例触发器。
正确的选择完全取决于你想做什么。
- 不,区别不只是"特殊情况"。因为设置/查询会话的时区,所以值的涉及方式不同。
- 我很高兴你写了"正确的决定完全取决于你想做什么"。在SE这个状态下,答案太多了,没有充分的理由,"你不能做X"或"你必须永远做Y"。
时间戳总是以UTC(即1970-01-01以来经过的秒数,以UTC为单位),而您的MySQL服务器会自动将其转换为服务器时区的日期/时间。从长远来看,时间戳是一种可行的方法,因为您知道时间数据将始终采用UTC格式。例如,如果迁移到其他服务器或更改服务器上的时区设置,则不会搞砸日期。
日期时间、时间戳和日期之间的比较

那是什么[分数]?
- 日期时间或时间戳值可以包括尾随小数秒精度高达微秒(6位)。在特别是,插入日期时间的值中的任何小数部分或者时间戳列被存储而不是丢弃。这当然是可选的。
资料来源:
- mysql日期/时间数据类型引用
- MySQL存储需求参考
在MySQL中值得注意的是,在创建表列时,可以使用以下几行中的内容:
这将更新您修改行的每个实例的时间,有时对存储的上次编辑信息非常有用。这只适用于时间戳,而不是日期时间。
- dev.mysql.com/doc/refman/5.6/en/timestamp initialization.htm‌&8203;l
- 日期时间现在更新到5.6.5。
在使用mysql和php时,我总是使用unix时间戳。其主要原因是PHP中的默认日期方法使用时间戳作为参数,因此不需要解析。
要在php中获取当前的unix时间戳,只需执行EDOCX1[0]在mysql中做SELECT UNIX_TIMESTAMP();。
- -1我实际上认为下面的答案更好—使用datetime可以将更多的日期处理逻辑推送到MySQL本身中,这非常有用。
- 有没有基准测试显示MySQL中的排序比PHP慢?
- 嗯,这要看情况而定,有时候当我们不喜欢使用strtotime时,使用它是件好事。(PHP5.3 DEP)
- 如果需要的话,只需使用from unixtime就可以将逻辑推送到mysql中。
- 我曾经在PHP应用程序和MySQL中使用过所有的Unix时间戳,但是我发现在MySQL中将日期和时间存储为原生日期/时间类型要方便得多。这对于报告和浏览数据集特别有用。随着时间的推移,当我不得不复制/跳过Unix时间戳时,我开始切换。我很确定有性能和其他优点/缺点,但根据您的用例便利性,可能比相当小的优化更重要。
根据我的经验,如果您想要一个日期字段,其中插入只发生一次,并且您不希望在该特定字段上有任何更新或任何其他操作,请使用日期时间。
例如,考虑一个带有注册日期字段的user表。在该user表中,如果您想知道特定用户最后一次登录的时间,请使用timestamp类型的字段,以便更新该字段。
如果从phpmyadmin创建表,则当行更新时,默认设置将更新时间戳字段。如果时间戳文件没有使用行更新进行更新,则可以使用以下查询使时间戳字段自动更新。
timestamp数据类型以UTC格式存储日期和时间,而不是像date time那样以当前时区格式存储。当您获取数据时,时间戳会再次将其转换为当前时区时间。
所以假设你在美国,从一个有美国时区的服务器上获取数据,然后根据美国时区来获取日期和时间。timestamp数据类型列在其行更新时总是自动更新。因此,跟踪上次更新特定行的时间非常有用。
有关更多详细信息,您可以阅读博客文章时间戳与日期时间。
我总是使用unix时间戳,只是在处理大量日期时间信息时保持清醒,特别是在对时区进行调整、添加/减去日期等操作时。在比较时间戳时,这排除了时区的复杂因素,并允许您在服务器端处理(无论是应用程序代码还是数据库查询)中节省资源,因为您使用的是轻量级算法,而不是较重的日期时间加/减函数。
另一件值得考虑的事情是:
如果您正在构建一个应用程序,您永远不知道如何使用您的数据。如果最终不得不,比如说,将数据集中的一组记录与第三方API中的一组项目进行比较,然后说,将它们按时间顺序排列,您将很乐意为您的行设置Unix时间戳。即使您决定使用MySQL时间戳,也要存储一个Unix时间戳作为保险。
本文引用:
主要区别:
用于跟踪记录更改并在每次更改记录时更新的时间戳。用于存储特定值和静态值的日期时间,这些值不受记录中任何更改的影响。
时间戳还受不同时区相关设置的影响。日期时间是常量。
时间戳在内部将当前时区转换为用于存储的UTC,并在检索期间转换回当前时区。日期时间不能这样做。
时间戳支持的范围:'1970-01-01 00:00:01'UTC到'2038-01-19 03:14:07'UTC日期时间支持的范围:'1000-01-01 00:00:00'至'9999-12-31 23:59:59'
在表上执行UPDATE语句时,注意时间戳的更改。如果您有一个列为'name'(varchar)、'age'(int)和'date_added'(timestamp)的表,则运行以下DML语句
然后,"添加日期"列中的每个值都将更改为当前时间戳。
- 根据表的设置方式,可以控制此行为。查看dev.mysql.com/doc/refman/5.5/en/timestamp initialization.htm‌&8203;l
- @Charlesfaiga的默认行为是在更新任何其他列时更新时间戳。如果希望时间戳保留其原始值,则必须显式关闭此选项。
在我的例子中,我将UTC设置为所有东西的时区:系统、数据库服务器等,每次我都可以。如果我的客户需要另一个时区,那么我会在应用程序中对其进行配置。
我几乎总是喜欢时间戳而不是日期时间字段,因为时间戳隐式地包含时区。因此,由于从不同时区的用户访问应用程序的那一刻起,您希望他们在本地时区中查看日期和时间,因此与将数据保存在日期时间字段中相比,此字段类型使得执行此操作非常容易。
另外,如果将数据库迁移到具有另一个时区的系统,我会更加自信地使用时间戳。在计算两个时刻之间的差异时,不要说可能的问题,因为在这两个时刻之间的时间变化比较短,需要1小时或更短的精度。
因此,总的来说,我看重时间戳的优点:
- 可在国际(多时区)应用程序上使用
- 在时区之间轻松迁移
- 很容易计算差异(只需减去两个时间戳)
- 不用担心夏天的约会
出于所有这些原因,我选择可以设置的UTC时间戳字段。我避免头痛;)
timestamp和datetime的另一个区别是timestamp,不能将值默认为空。
- 这显然是错误的。这里有一个例子:CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);第一列可以接受空值。
主要区别是
看看这篇文章,看看日期时间索引的问题。
- 如果使用基于列值的函数进行选择,则两者都有相同的问题,并且都可以被索引。
- 索引在时间戳上工作,而不在日期时间上工作?你从这些帖子中得出了错误的结论。
我发现时间戳在不使用不必要的触发器的情况下根据当前时间自动更新自身的能力中具有无与伦比的有用性。虽然时间戳和上面说的一样是UTC,但那只是我。
它可以跟踪不同时区,因此,如果您需要显示相对时间,例如,UTC时间就是您想要的。
1 2 3 4 5 6 7 8 9
| +---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP | DATETIME |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes. | DATETIME requires 8 bytes. |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00: 00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format. |
| TIMESTAMP supported range: ‘ 1970-01-01 00: 00: 01′ UTC to ‘ 2038-01-19 03: 14: 07′ UTC. | DATETIME supported range: ‘ 1000-01-01 00: 00: 00′ to ‘ 9999-12-31 23: 59: 59′ |
| TIMESTAMP during retrieval converted back to the current time zone. | DATETIME can not do this. |
| TIMESTAMP is used mostly for metadata i.e. row created /modified and audit purpose. | DATETIME is used mostly for user -data. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+ |
我更喜欢使用时间戳,以便将所有内容保持为一种常见的原始格式,并以PHP代码或SQL查询格式设置数据。在某些情况下,在代码中,它可以很方便地将所有内容保持在几秒钟之内。
我喜欢unix时间戳,因为您可以将其转换为数字,只需担心数字。再加上加/减和获取持续时间等,然后以任何格式将结果转换为日期。此代码找出从文档传递时间戳到当前时间之间的时间(分钟)。
1 2 3 4 5
| $date = $item ['pubdate']; (etc ... )
$unix_now = time();
$result = strtotime ($date , $unix_now );
$unix_diff_min = (($unix_now - $result ) / 60);
$min = round($unix_diff_min ); |
- 或者,使用人类可读的本机mysql datetime,并使用本机mysql函数添加/删除日期时间。
TIMESTAMP需要4个字节,而DATETIME需要8个字节。
到目前为止还没有提到,默认的当前时间戳只适用于时间戳,而不适用于日期时间类型字段。
这与只能使用日期时间而不能使用时间戳的MS Access表相关。
- mysql 5.6中增加了对DATETIME的DEFAULT CURRENT_TIMESTAMP支持。
- "CURRENT_TIMESTAMP的任何同义词与CURRENT_TIMESTAMP的含义相同。这些是CURRENT_TIMESTAMP(), NOW(), LOCALTIME, LOCALTIME(), LOCALTIMESTAMP和LOCALTIMESTAMP()。->mysql文档
当您有来自不同国家、不同时区的访客时,时间戳非常有用。您可以轻松地将时间戳转换为任何国家/地区时区
我只在存储UTC时使用无符号BIGINT…
它仍然可以在PHP中调整为本地时间。
用FROM_UNIXTIME( integer_timestamp_column )选择DATETIME。
显然,应该在该列上设置一个索引,否则就不会有任何进展。
这里有很多答案建议将其存储为时间戳,以防需要表示定义良好的时间点。但是,如果您按照约定将时间点全部存储在UTC中,那么您还可以使用datetime获得时间点。
- 你能给我一些理由为什么我更喜欢这个而不是使用时间戳吗?
- @贾西尔不是真的,这似乎是一场大辩论。我只是指出,如果有一个约定将所有日期时间存储在特定时区(即UTC)中,日期时间可以表示特定的时间点。就我个人而言,我会将所有内容存储在datetime中,时间戳限制在2038年(即使我猜他们最终会对此做些什么),如果我在db中查看一些原始数据,datetime将是可读的,而不必应用转换。同样,这是非常主观的。
在遇到许多与时区相关的问题和错误后,我停止在应用程序中使用datetime。在大多数情况下,使用timestamp的imho优于datetime。
当你问什么时候?答案就像是"2019-02-05 21:18:30",没有完成,没有定义答案,因为它缺少另一个部分,在哪个时区?华盛顿?莫斯科?北京?
使用不带时区的日期时间意味着您的应用程序只处理1个时区,但是时间戳为您提供了datetime的好处,以及在不同时区显示相同精确时间点的灵活性。
这里有一些情况会让您后悔使用datetime,并希望您将数据存储在时间戳中。
为了让您的客户感到舒适,您希望根据他们喜欢的时区向他们显示时间,而不必让他们进行数学运算,并将时间转换为有意义的时区。您所需要的只是更改时区,并且您的所有应用程序代码都将是相同的。(实际上,您应该总是在应用程序开始时定义时区,或者在PHP应用程序的情况下定义请求处理)
您更改了您所居住的国家,并继续在不同时区查看数据时维护数据的工作(而不更改实际数据)。
您接受来自世界各地不同客户机的数据,每个客户机都将时间插入其时区。
简而言之
datetime=应用程序支持1个时区(用于插入和选择)
timestamp=应用程序支持任何时区(用于插入和选择)
这个答案仅仅是为了突出时间戳的灵活性和易用性,当涉及到时区时,它不包括任何其他的差异,如列大小、范围或分数。
如果您想保证您的应用程序在2038年2月不会运行,请使用timestamp。有关支持的日期范围,请参阅参考资料。
TIMESTAMP是计算机通过网络时间协议(NTP)记录的事件的当前时间。
DATETIME是在PHP配置中设置的当前时区。