SQL Server中的datetime2 vs DateTime

DateTime2 vs DateTime in SQL Server

哪一个:

  • datetime
  • datetime2

是否建议在SQL Server 2008+中存储日期和时间?

我知道精度(可能还有存储空间)上的差异,但现在忽略了这些差异,是否有关于何时使用什么的最佳实践文档,或者我们应该只使用datetime2


datetime的msdn文档建议使用datetime2。以下是他们的建议:

Use the time, date, datetime2 and
datetimeoffset data types for new
work. These types align with the SQL
Standard. They are more portable.
time, datetime2 and datetimeoffset
provide more seconds precision.
datetimeoffset provides time zone
support for globally deployed
applications.

日期时间2具有更大的日期范围、更大的默认小数精度和可选的用户指定精度。另外,根据用户指定的精度,它可能使用较少的存储空间。


DATETIME2的日期范围为"0001/01/01"到"9999/12/31",而DATETIME类型仅支持1753-9999年。

另外,如果需要,DATETIME2在时间方面更精确;日期时间限制为3 1/3毫秒,而DATETIME2可以精确到100ns。

两种类型都映射到.NET中的System.DateTime—没有区别。

如果您有选择,我建议您尽可能使用DATETIME2。我看不到使用DATETIME有什么好处(除了向后兼容性),您的麻烦会少一些(日期超出范围,这样麻烦就少了)。

另外:如果你只需要日期(不需要时间部分),那么就使用日期——它和DATETIME2一样好,也可以节省你的空间!:-)同样只适用于时间-使用TIME。这就是这些类型的产品的用途!


除了(旧应用程序兼容性)之外,datetime2在大多数方面都获胜。

  • 较大的值范围
  • 较好精度
  • 较小的存储空间(如果指定了可选的用户指定精度)
  • SQL Date and time data types compare - datetime,datetime2,date,TIME

    请注意以下几点

    • 句法
      • 日期时间2[(分数秒精度=>低于存储大小)]
    • 精度,刻度
      • 0到7位,精度为100ns。
      • 默认精度为7位。
    • 存储容量
      • 精度小于3的6个字节;
      • 精度3和4为7字节。
      • 所有其他精度都需要8个字节。
    • datetime2(3)的位数与datetime相同,但使用7字节的存储空间而不是8字节(sqlhints-datetime vs datetime2)
    • 有关datetime2的详细信息(Transact-SQL msdn文章)

    图像来源:MCTS自定步调培训工具包(考试70-432):微软?SQL Server?2008-实施和维护第3章:表格->第1课:创建表格->第66页


    我同意@marc_s和@adam_poward——datetime2是向前发展的首选方法。它具有更宽的日期范围、更高的精度,并且使用相同或更少的存储空间(取决于精度)。

    然而,有一件事没有引起讨论……@马克·库斯(Marc_)的国家:埃多克斯(EDOCX1)(9)。但是,这是正确的,相反的情况是不正确的……在进行日期范围搜索时,这很重要(例如,"查找2010年5月5日修改的所有记录")。

    .NET版本的DATETIME的范围和精度与DATETIME2相似。当将.NET DATETIME向下映射到旧的SQL DATETIME时,会发生隐式舍入。旧的SQL DATETIME精确到3毫秒。这就是说,11:59:59.997是最接近一天结束的。任何更高的数字都会被四舍五入到第二天。

    试试这个:

    1
    2
    3
    4
    DECLARE @d1 datetime   = '5/5/2010 23:59:59.999'
    DECLARE @d2 datetime2  = '5/5/2010 23:59:59.999'
    DECLARE @d3 datetime   = '5/5/2010 23:59:59.997'
    SELECT @d1 AS 'IAmMay6BecauseOfRounding', @d2 'May5', @d3 'StillMay5Because2msEarlier'

    避免这种隐式舍入是移动到datetime2的重要原因。日期的隐式舍入显然会导致混淆:

    • SQL Server中的奇怪日期时间行为
    • http://bytes.com/topic/sql-server/answers/578416-grand-millisecond-part-datetime-data-sql-server-2000-a
    • SQL Server 2008和毫秒
    • http://improve.dk/archive/2011/06/16/getting-bit-by-datetime-rounding-or-why-235959-999-ltgt.aspx
    • http://milesquaretech.com/blog/post/2011/09/12/datetime-vs-datetime2-sql-is-rounding-my-999-millises!ASPX


    如果您是一个访问开发人员,试图将now()写入相关字段,那么datetime2会造成严重破坏。刚刚执行了一个access->sql2008r2迁移,它将所有datetime字段都作为datetime2放入。在值被弹出时用now()追加一条记录。2012年1月1日下午2:53:04可以,但2012年10月1日下午2:53:04不行。

    一旦性格改变了。希望它能帮助别人。


    几乎所有的答案和评论都是关于正反两面的。以下是迄今为止所有利弊的概述,以及一些关键的利弊(在下面的2中),我只看到提到过一次或根本没有提到过。好的。

  • 赞成的意见:
  • 1.1。更符合ISO(ISO 8601)(尽管我不知道这在实践中是如何发挥作用的)。好的。

    1.2。更大的范围(1/1/0001至12/31/9999对1/1/1753-12/31/9999)(尽管额外的范围,所有在1753年之前,除了在历史、天文、地质等应用中,可能不会被使用)。好的。

    1.3。与.NET的DateTime类型的范围完全匹配(尽管如果值在目标类型的范围和精度范围内,除了下面的con 2.1之外,两个值之间的转换都不需要特殊编码,否则将发生错误/舍入)。好的。

    1.4。更精确(100纳秒,即0.000000,1秒与3.33毫秒(即0.003,33秒)相比(尽管除了在工程/科学应用中,可能不会使用额外的精度)。好的。

    1.5。当配置为与Iman Abidi所宣称的相似(1毫秒不是"相同"(3.33毫秒)时,DateTime的精度使用更少的空间(7对8字节),但当然,您将失去精度优势,这可能是两个(另一个是范围)中最受欢迎的一个(尽管可能是不必要的优势)。好的。

  • 欺骗:
  • 2.1。当将参数传递给.NET SqlCommand时,如果传递的值超出了SQL Server DateTime的范围和/或精度,则必须指定System.Data.SqlDbType.DateTime2,因为它默认为System.Data.SqlDbType.DateTime。好的。

    2.2。在使用数值和运算符的SQL Server表达式中,无法隐式/轻松地转换为浮点数值(自最小日期时间以来的天数)值,以便对其执行以下操作:好的。

    2.2.1加减天数或部分天数。注意:当您需要考虑到日期时间的多个部分(如果不是所有部分)时,使用DateAdd函数作为解决方法并不容易。好的。

    2.2.2.为了计算"年龄",取两个日期时间之间的差额。注意:您不能简单地使用SQL Server的DateDiff函数,因为它不像大多数人预期的那样计算age,因为如果两个日期时间正好跨越指定单位的日历/时钟日期时间边界,即使是该单位的一小部分,它也会返回该单位与0之间的差额。例如,如果两个日期时间在不同的日历日(即"1999-12-31 23:59:59.999999"和"2000-01-01 00:00:00.0000000"),那么两个日期时间间隔只有1毫秒的DateDiff中的DateDiff将返回1对0(天)。相同的1毫秒差异日期时间如果移动到不跨越日历日,将返回0(天)的Day中的"datediff"。好的。

    2.2.3.取日期时间的Avg(在聚合查询中),只需先转换为"float",然后再转换回DateTime。好的。

    注意:要将DateTime2转换为数字,您必须执行以下公式,该公式仍然假定您的值不小于1970年(这意味着您将失去所有额外范围加上217年)。注意:您可能无法简单地调整公式以允许额外的范围,因为您可能会遇到数字溢出问题。好的。

    25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0–来源:"https://siderite.blogspot.com/2015/08/how-to-translate-t-sql-datetime2-to.html"好的。

    当然,你也可以先从CastDateTime(如果必要的话,再回到DateTime2),但是你会失去DateTime2DateTime的精度和范围(所有这些都是1753年以前的)好处,而DateTime2DateTime是最大的两个,同时也是最不可能需要的两个,这就引出了一个问题:为什么在需要的时候使用它?对于加减/年龄(与DateDiff/Avg相比),您将失去隐式/易转换为浮点数字(天)的计算优势,这在我的经验中是一个很大的优势。好的。

    顺便说一句,日期时间的Avg是(或至少应该是)一个重要的用例。a)除了用于获取日期时间(自公共基准日期时间以来)用于表示持续时间(一种常见做法)时的平均持续时间外,b)还可以获取仪表板类型的统计信息,了解一个范围/一组行的日期时间列中的平均日期时间。c)监控/排除列中可能不再有效和/或可能需要弃用的值的标准(或至少应该是标准的)即席查询是为每个值列出事件计数和(如果可用)与该值相关联的MinAvgMax日期时间戳。好的。好啊。


    here is an example,the Show You Will之间的大小(字节)存储datetime和smalldatetime类型之间,datetime2(0),(7):与datetime2P></

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    DECLARE @temp TABLE (
        sdt smalldatetime,
        dt datetime,
        dt20 datetime2(0),
        dt27 datetime2(7)
    )

    INSERT @temp
    SELECT getdate(),getdate(),getdate(),getdate()

    SELECT sdt,DATALENGTH(sdt) AS sdt_bytes,
        dt,DATALENGTH(dt) AS dt_bytes,
        dt20,DATALENGTH(dt20) AS dt20_bytes,
        dt27, DATALENGTH(dt27) AS dt27_bytes FROM @temp

    which归来P></

    1
    2
    sdt                  sdt_bytes  dt                       dt_bytes  dt20                 dt20_bytes  dt27                         dt27_bytes
    2015-09-11 11:26:00  4          2015-09-11 11:25:42.417  8         2015-09-11 11:25:42  6           2015-09-11 11:25:42.4170000  8

    我知道如果我第二次到店信息- but not to the millisecond -可以保存datetime2 each如果使用2字节(0)instead of datetime或datetime2(7)。P></


    当increased there is with some clients datetime2精密,不支持或日期,时间和力量,你datetime2 convert to literal字符串。专门开发的"唐氏mentions Microsoft ODBC,OLE DB级",这些问题与JDBC和SqlClient数据,在图表类型和how each has the map可以表现型。P></

    如果电压值compatability精密,使用datetimeP></


    对字符串和日期datetimeinto of datetime2can be when using不太一样,中美DATEFORMATsettings。例如P></

    1
    2
    3
    4
    SET dateformat dmy
    DECLARE @d datetime, @d2 datetime2
    SELECT @d = '2013-06-05', @d2 = '2013-06-05'
    SELECT @d, @d2

    2013-05-06归来》(即5和6 datetime)for(即六月5,2013-06-05for datetime2)。不管一个人多,与DATEFORMATto mdy集,都@d@d22013-06-05和回车。P></

    the datetime行为似乎在MSDN文档SET DATEFORMATOR with the which some of character strings:美国formats for example,ISO 8601,interpreted DataFormat independently are of the setting。明显不是真的!P></

    直到我bitten by this,that yyyy-mm-dd我总是一只会思想handled好吧,regardless of the Language Settings /地方。P></


    老问题。但我想stated add something by not already here的人……(注:这是我自己的观察,我不知道任何参考ask for)P></

    datetime2 is when used in filter标准更快。P></

    TLDR:P></

    我在SQL表中与2016年百千行和datetime时间因为它_ column条目来店时间精确up to the seconds。在同时执行多joins复合查询与子查询的布尔used as,when where子句的:P></

    1
    WHERE ENTRY_TIME >= '2017-01-01 00:00:00' AND ENTRY_TIME < '2018-01-01 00:00:00'

    最后initially when there was the query是hundreds of Rows rows,but when the number of increased查询开始,给这个误差:P></

    1
    2
    Execution Timeout Expired. The timeout period elapsed prior
    TO completion OF the operation OR the server IS NOT responding.

    在这些条款和unexpectedly removed the,the Run,查询是在1秒,尽管现在使用的是在一fetched for。在茶内运行查询和条款,我和它没有在第85秒,和0.01 secs恩了。P></

    多线程的肉类在这里this as DateTime的过滤性能问题。P></

    optimized查询到的数据位。but the real was by changing the速得datetime2 DateTime column to。P></

    查询超时时间一样,现在需要在第二previously less。P></

    干杯P></


    根据这一条,如果你会喜欢have the same精密使用简单的DateTime datetime2 of You have to datetime2使用(3)。这应该给你一个不一样的精密跟踪,提供安fewer字节,和扩大范围。P></


    我只是在一个更多stumbled for datetime2优势:avoids bug in the Python模块adodbapi,which吹弹出如果标准库passed which has datetime值是非零microseconds for a column but if the datetime工作结束定义datetime2column is as。P></


    1
    2
    SELECT ValidUntil + 1
    FROM Documents

    the above SQL与datetime2场不会工作。恩归来"和错误的操作数是不兼容与datetime2型冲突:int"P></

    增1 to get the next day is something with have been for developers做一年。现在有一场超微软新datetime2 that cannot handle this simple功能性。P></

    "让我们用新型that is this比原有老人",我不想知道!P></


    我认为最好的方式datetime2 is the to store the日期,因为它有更多的效率比the的DateTime。你可以使用在SQL Server 2008 datetime2店日期和时间,它需要6~8个字节,在商店和has to nanoseconds精密of 100。任何人谁需要知道时间会想datetime2更精密。P></