【问题标题】:Store incomplete date in MySQL date field在 MySQL 日期字段中存储不完整的日期
【发布时间】:2011-07-30 11:21:26
【问题描述】:

我想为用户提供引入不完整日期的可能性(例如,仅 2005 年或 1998 年 1 月),但也可以提供包含年、月、日的完整日期。我可以使用数据库中的单个日期字段来完成此操作吗?

我已经尝试过UPDATE tableA SET mydate = '2001-00-00',它似乎可以工作(没有错误),但我不确定这是否正确。在内部我假设使用了时间戳,那么 MySQL 如何表示那些 0?

【问题讨论】:

  • 查询SELECT mydate FROM tableA会得到什么?
  • 正确的值,即 2001-00-00。我担心的是我正在利用一些非标准行为,这些行为依赖于某些可能有一天会中断或在某些情况下不起作用的技巧。

标签: mysql date


【解决方案1】:

documentation for the DATE_FORMAT() 中有一条关于 MySQL 允许不完整日期的小注释:

月份和日期说明符的范围从零开始,因为 事实上,MySQL 允许存储不完整的日期,例如 '2014-00-00'。

正如@wonk0 所指出的,当ALLOW_INVALID_DATES 未设置时,MySQL 会将无效日期设置为0000-00-00 00:00:00。然而,即使没有设置ALLOW_INVALID_DATES,插入一个有效的年份并将月份和日期设置为零似乎也不会触发这种行为——至少在我的测试中没有(MySQL 5.1.54-1ubuntu4)。我之前使用过这个功能没有任何问题,但到目前为止我还没有找到任何更详细的文档来完整地描述这个行为。

日期/时间比较似乎也能按预期工作:例如,2011-01-00 > 2011-00-002011-00-01 > 2011-00-00 会按预期工作。

更新

请参阅this answer(由另一位迈克)回答类似问题。它指向 The Definitive Guide to MySQL 5 的摘录:

在旧版本的 MySQL 中,DATE 和 DATETIME 数据类型只 有限数量的类型检查。介于 0 和 12 之间的值 月,通常允许使用 0 和 31 表示天数。然而,它是 客户程序提供正确数据的责任。 (为了 例如,0 是一个月或一天的允许值,以便 提供存储不完整或未知数据的可能性。)

从 MySQL 5.0.2 开始,有更彻底的验证,所以 只能存储有效数据。仍然允许月份和 日期值 0,以及日期 0000-00-00。

【讨论】:

  • 使用时间戳来存储日期的假设是否不正确?因为我不明白您如何将 2011-00-00 表示为时间戳。
  • @Omar Kohl:是的,我认为这个假设是不正确的。 TIMESTAMP 的范围小于 DATETIMEDATETIME 使用 8 个字节,而 TIMESTAMP 使用 4 个字节。见Data Type Storage Requirements
  • 优秀的答案,我找到的最好的答案。
  • 不幸的是,在 MySQL 5.7+ 上似乎默认不允许这种行为:dev.mysql.com/doc/refman/5.7/en/…
【解决方案2】:

好吧,如果您使用日期字段,那么您应该期待那些 0。摆脱它们的一种方法是使用varchar 选择。但是,最好使用日期字段,因为那是存储在那里的内容。

如果您必须允许用户输入不完整的日期,那么它必须是 varchar,在这种情况下,您可以使用脚本格式化输入并存储在该列中

【讨论】:

  • 那将是我最后的选择。当然,日期格式的东西总是更适合订购等。
  • 是的,所以不要让用户格式化日期,我建议你只允许 sql 格式化当前的 datetimestamp 那里
【解决方案3】:

存储部分日期取决于 MySQL 运行的 sql 模式。请阅读http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html,尤其是http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_allow_invalid_dates 中的无效日期。

【讨论】:

  • "ALLOW_INVALID_DATES:不执行完整的日期检查。仅检查月份是否在 1 到 12 的范围内,日期是否在 1 到 31 的范围内。"在这种情况下,它不适用,因为月份和日期都不在该范围内......(均为 00)
  • Check only that the month is in the range from 1 to 12 and the day is in the range from 1 to 31 为什么这允许一个月或一天为 0 ?
猜你喜欢
  • 2019-01-21
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 1970-01-01
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多