日期与时间型理论上应该是用的最多的,不管是什么时候,都需要使用时间,用户登录,文章编辑,甚至LOG,哪个不需要时间?然而在真正的应用中,却没有多少人在使用日期与时间型字段,大多数人都是使用int的时间戳来替代了日期型字段。那么,究竟应该怎样正确使用呢?日期型字段的优劣是什么?今天稍微介绍一下。
在MYSQL数据库中,关于日期和时间型字段有四种,date,time,datetime,year,还有一种比较特殊的timestamp字段。下面将一一介绍。
类型 | 含义 |
DATE | Y-m-d的时间格式,取值范围1000-01-01~9999-12-31,占用3个字节 |
TIME | H:i:s的时间格式,取值范围-838:59:59~+838:59:59,占用3个字节(说实话,我没有理解这个取值范围) |
DATETIME | Y-m-d H:i:s的时间格式,是DATE+TIME的组合 |
YEAR | 年份,取组范围1901~2155和0000,占用一个字节,YEAR有2位和4位之分,4位的就是前面的取值范围,2位的取值范围为70~69,代表了1970~2069 |
TIMESTAMP | 虽然这个TIMESTAMP并非传统意义上的时间戳,但它的取值范围还是符合时间戳的标准,即从1970~2037,基本格式为:Y-m-d H:i:s,在以前的版本里,日期与时间之间并没有空格,如果为了兼容老的数据,在查询的时候则需要使用:select ts+0 from table来获取正确的时间 |
MYSQL在早期版本里对于时间类型的缺乏严格的判断,而只是仅仅判断数值是否在一个区间,却并不判断它是否合法:月份值允许0~12,日期值允许1~31,所有的数据验证都是由客户端判断好而数据库这边仅仅是一个存储作用。但这在5.0.2版本的时候,一切有了很大的改观,MYSQL开始对日期与时间型数据的判断非常严格,只有它认为合法的数据才存储到数据库,当然它认为0000-00-00仍然是合法数据。
不过,这仍然需要对MYSQL的系统变量sql_mode进行设置,大致有以下三个设置值:
1、ALLOW_INVALID_DATES 即不对数据有效性进行判断,仍然允许存入有明显错误的时间,比如:2001-02-31
2、NO_ZERO_DATE 在这种模式下,0000-00-00不再认为是合法日期
3、NO_ZERO_IN_DATE 不允许使用0作为月份值或者日期值
对于DATE,TIME,DATETIME,YEAR这四种格式,大家都可以从名字上能够看出来格式或者规范是什么样的,真正特殊的是TIMESTAMP格式。
对于TIMESTAMP格式,我想,用PHP开发的人应该是非常熟悉,时间戳嘛。在PHP里面直接使用time()函数,返回的就是当前时间的时间戳。可是,在MYSQL里,TIMESTAMP的存储值和PHP里的TIMESTAMP并不一样,就象上文说的,它存储的格式和DATETIME是一样的,只是它是自动存入的。
当你的表存在TIMESTAMP字段时,如果你对其他字段的内容进行修改,这个字段的值也会随之更新,几乎可以这么理解,这个字段就是MYSQL给你提供的数据记录的最后一次更新时间,正因为这个原因,所以TIMESTAMP字段大多数时候都是被用来管理和检查数据使用,而不会用来存储实际数据(因为一旦其他数据有更新,它就会自动更新)。
有一些需要与客户端程序或者函数进行交互的数据库操作,只有在数据表里存在一列TIMESTAMP字段才能正常工作,如Connector/ODBC,事实上就连MYSQL在对数据进行内部管理的时候,也需要知道它们的最后一次修改时间。虽然说该字段会被自动更新,但如果你在INSERT、UPDATE的时候,如果你指定了该字段的值,默认就会使用该值插入数据表。如果一个表里面有多个字段有TIMESTAMP属性,那么默认MYSQL是更新第一个有此属性的字段。
TIMESTAMP并没有想象中的那么不可控制,从mysql4.1.3开始,MYSQL为TIMESTAMP增加了两个属性,它们可以让用户更好的调控对TIMESTAMP列的刷新行为,使得这个字段可以更加好的为我们服务。
设置类型 | 含义 |
TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 在创建新记录或者修改现有记录的时候对这个数据列进行刷新 |
TIMESTAMP | 行为同上 |
TIMESTAMP DEFAULT CURRENT_TIMESTAMP | 只在创建新记录的时候才刷新这个值,以后更新等操作时不会进行修改 |
TIMESTAMP ON UPDATE CURRENT_TIMESTAMP | 在创建新记录的时候设置值为0,在修改的时候才会更新它。 |
TIMESTAMP DEFAULT 'YYYY-mm-dd hh:mm:ss' ON UPDATE CURRENT_TIMESTAMP | 在创建新记录的时候设置值为指定值,以后在修改的时候刷新它。 |
有时候我们需要在时间列里面存入微秒,但目前而言,MYSQL还不能存储这样的结果。虽然这样的相关函数已经存在。
虽说MYSQL的日期格式往往都是'yyyy-mm-dd'这样的格式,但其实在insert和update的时候,还是可以接受'yyyy/mm/dd'这种符合日期规范格式的数据。所以,不要太担心。
对于日期处理,在SQL里面用date_format,format_unix等,这类函数太多了。如果以后有空我会慢慢介绍。