何时使用VARCHAR和DATE / DATETIME

时间:2011-01-21 12:43:40

标签: sql date

我们在Freenode上进行了这个编程讨论,当我尝试使用VARCHAR(255)以这种格式存储日期变量时出现了这个问题:D / MM / YYYY。所以问题是为什么使用VARCHAR存储日期这么糟糕。以下是优点:

  1. 编码速度更快。以前我使用DATE,但日期格式化是一个真正的痛苦。
  2. 使用字符串比使用Date更耗电吗?谁在乎,我们生活在Ghz时代。
  3. 它在道德上不正确(lolwut?)这是其他用户告诉我的......
  4. 那么您希望用什么来存储日期? SQL VARCHAR还是SQL DATE?

5 个答案:

答案 0 :(得分:40)

  

为什么不用锤子拧上螺丝?

因为它不适合这项工作。

VARCHAR版本的一些缺点:

  • 您无法轻松地将天数添加/减去VARCHAR版本。
  • 提取月/年更难。
  • 没有什么能阻止您将非日期数据放入数据库的VARCHAR列中。
  • VARCHAR版本是特定于文化的。
  • 您无法轻松排序日期。
  • 如果您想稍后更改格式,则很难。
  • 这是非常规的,这将使其他开发者更难理解。
  • 在许多环境中,使用VARCHAR会占用更多存储空间。这可能与少量数据无关,但在拥有数百万行数据的商业环境中,这可能会产生很大的不同。

当然,在你的爱好项目中,你可以做你想做的事。在专业的环境中,我坚持使用正确的工具。

答案 1 :(得分:15)

如果您拥有超过2-3百万行的数据库,您就会知道为什么使用DATETIME比使用VARCHAR更好:)

简单的答案是,对于数据库 - 处理能力不再是问题。只是数据库大小是因为HDD的寻道时间。

基本上,对于现代硬盘,如果以随机顺序(通常是这种情况)读取,您可以读取大约100条记录/秒,因此您必须尽一切可能将数据库大小降至最低,因为:

  • 硬盘驱动器的磁头不必“移动”这么多
  • 您将在RAM中容纳更多数据

最后硬盘的寻道时间总会让你失望。例如。一些简单的带有多行的GROUP BY查询在磁盘上完成时可能需要几个小时,相比之下,在RAM =>完成时需要几秒钟。因为寻求时间。

对于VARCHAR,您无法进行任何搜索。如果你讨厌SQL如何处理日期的方式,那么只需在32位整数字段中使用unix时间戳。您将(基本上)使用SQL DATE字段的所有优点,您只需使用您选择的编程语言操作和格式化日期,而不是SQL函数。

答案 2 :(得分:6)

有两个原因:

  • 按日期排序结果
  • 对日期格式更改不敏感

所以让我们举一组看起来像这样的记录:

5/12/1999 | Frank N Stein
1/22/2005 | Drake U. La
10/4/1962 | Goul Friend

如果我们按照您的方式存储数据,但按照订单中的日期排序,SQL将使用如下所示的结果集进行响应:

1/22/2005 | Drake U. La
10/4/1962 | Goul Friend
5/12/1999 | Frank N. Stein

如果我们将日期存储为DATETIME,那么SQL将正确地响应它们,如下所示:

10/4/1962 | Goul Friend
5/12/1999 | Frank N. Stein
1/22/2005 | Drake U. La

此外,如果您需要以不同的格式显示日期,例如YYYY-MM-DD,那么您需要转换所有数据或处理混合内容。当它作为SQL DATE存储时,您将被迫在代码中进行转换,并且很可能有一个位置可以更改格式以显示所有日期 - 免费。

答案 3 :(得分:3)

DATE/DATETIMEVARCHAR之间的日期,我每次都会使用DATE/DATETIME。但是有一个被忽视的第三种选择。将其存储为未签名的INTEGER!

我决定在我的上一个项目中使用INTEGER unsigned,我对做出这个选择感到非常满意,而不是将其存储为DATE/DATETIME。因为我在客户端和服务器之间传递日期,所以它是我使用的理想类型。而不是必须将其存储为DATE并且每次我选择时都必须转换回来,我只是选择并使用它,但我想要它。如果您想将日期选为“人类可读”日期,可以使用FROM_UNIXTIME()功能。

整数占用4个字节,而DATETIME占用8个字节。节省50%的存储空间。

Berin提出的排序问题也使用整数作为日期存储来解决。

答案 4 :(得分:3)

我投票赞成使用日期/日期时间类型,只是为了简单/一致。

如果您将其存储为字符串,请将其存储为ISO 8601格式:

其中,ISO 8601日期/时间字符串(A)正确整理,(B)是人类可读的,(C)是区域独立的,(D)可以容易地转换为其他格式。要符合ISO blurb标准,ISO 8601字符串提供

  

以下表示:

     
      
  • 日期
  •   
  • 一天中的时间
  •   
  • 协调世界时(UTC)
  •   
  • 偏移到UTC的本地时间
  •   
  • 日期和时间
  •   
  • 时间间隔
  •   
  • 重复时间间隔
  •   
     

表示可以采用以下两种格式之一:基本格式   具有最少数量的字符和扩展格式   添加字符以增强人类可读性。例如,   2003年1月3日可以表示为20030103   或2003-01-03。

     

[和]

     

提供了许多本地使用的优点   表示:

     
      
  • 系统易于阅读和编写
  •   
  • 易于比较和排序
  •   
  • 语言无关
  •   
  • 较大的单位写在较小的单位前面
  •   
  • 对于大多数表示,符号很短且长度不变
  •   

最后一件事:如果你需要做的就是存储一个日期,那么将它存储在char(8)列中的ISO 8601短格式YYYYMMDD中不会占用比日期时间值更多的存储空间(并且你不需要担心一天的最后一个滴答与下一个滴答的第一个滴答之间的3毫秒差距。但这是另一个讨论的问题。如果你把它分成3列 - YYYY char(4), MM char(2), DD char(2)你就会用光了相同的存储量,并获得更多的索引选项。更好的是,将字段存储为yyyy(4字节)的缩写,并为MM和DD中的每一个存储一个tinyint - 现在你的日期减少到6个字节当然,将日期组件分解为组成部分的缺点是转换为正确的日期/时间数据类型很复杂。