DateTime2与SQL Server中的DateTime
哪一个:
datetime
-
datetime2
是SQL Server 2008+中存储date和时间的推荐方法?
我意识到精度(和存储空间大概)的差异,但是现在忽略这些差异,有什么时候使用什么的最佳实践文档,或者我们应该只使用datetime2
?
datetime的MSDN文档build议使用datetime2 。 这是他们的build议:
使用时间,date,datetime2和datetimeoffset数据types的新工作。 这些types与SQL标准一致。 他们更便携。 时间,datetime2和datetimeoffset提供更多的秒精度。 datetimeoffset为全局部署的应用程序提供时区支持。
datetime2具有较大的date范围,较大的默认小数精度和可选的用户指定精度。 也取决于用户指定的精度,它可能使用较less的存储空间。
DATETIME2
的date范围为“0001/01/01”至“9999/12/31”,而DATETIME
types仅支持1753-9999年。
另外,如果您需要, DATETIME2
可以在时间上更精确; DATETIME被限制为3 1/3毫秒,而DATETIME2
可以精确到100ns。
这两种types映射到.NET中的System.DateTime
– 没有差别。
如果您有select,我会build议尽可能使用DATETIME2
。 我没有看到使用DATETIME
任何好处(除了向后兼容性) – 你会有更less的麻烦(date超出范围和麻烦就是这样)。
另外:如果你只需要date(没有时间部分),使用date – 它和DATETIME2
一样好,并且节省空间! :-)只用于时间 – 使用TIME
。 这就是这些types的!
datetime2除了(老应用程序兼容性)外,
- 更大的价值范围
- 更好的准确性
- 较小的存储空间 (如果指定了可选的用户指定的精度)
请注意以下几点
- 句法
- datetime2 [(分数秒精度=>查看下面的存储大小)]
- 精确,规模
- 0到7位数字,准确度为100ns。
- 默认精度是7位数。
- 存储大小
- 精度小于3的6个字节;
- 精度为3和4的7个字节。
- 所有其他精度需要8个字节 。
- DateTime2(3)与DateTime具有相同的位数,但使用7个字节的存储而不是8个字节( SQLHINTS-DateTime Vs DateTime2 )
- 在datetime2上查找更多(Transact-SQL MSDN文章)
图像来源: MCTS Self-Paced Training Kit(考试70-432):Microsoft®SQLServer®2008 – 实施和维护第3章:表格 – >第1课:创build表格 – >第66页
我同意@marc_s和@Adam_Poward – DateTime2是前进的首选方法。 它具有更广泛的date,更高的精度,并使用相同或更less的存储(取决于精度)。
讨论错过了一件事,但是…
@Marc_s状态: Both types map to System.DateTime in .NET - no difference there
。 这是正确的, 但是,反过来是不正确的 ……而且在做date范围search时很重要(例如“find我在5/5/2010修改的所有logging”)。
.NET的Datetime
版本与DateTime2
具有相似的范围和精度。 将.net Datetime
映射到旧的SQL DateTime
时,会发生隐式舍入 。 旧的SQL DateTime
精确到3毫秒。 这意味着11:59:59.997
就像你可以到达一天结束一样。 任何更高的东西都会收到第二天。
尝试这个 :
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的重要原因。 隐含的四舍五入date显然会造成混乱:
- SQL Server中奇怪的date时间行为
- http://bytes.com/topic/sql-server/answers/578416-weird-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-Milliseconds!.aspx
如果您是试图将Now()写入相关字段的Access开发人员,则DateTime2会造成严重破坏。 刚刚进行了Access – > SQL 2008 R2迁移,并将所有datetime字段放入DateTime2中。 用Now()追加一个logging作为轰炸的价值。 2012年1月1日下午2时53分04秒还好,但不是在2012年1月10日下午2时53分04秒。
一旦性格造成了差异。 希望它有助于某人。
下面是一个示例,它将显示smalldatetime,datetime,datetime2(0)和datetime2(7)之间存储大小(字节)和精度的差异:
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
哪个返回
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
所以,如果我想存储信息到秒 – 但不是毫秒 – 如果我使用datetime2(0)而不是datetime或datetime2(7),我可以节省2个字节。
在使用非美国DATEFORMAT
设置时,将datestring解释为datetime
和datetime2
可能也不同。 例如
set dateformat dmy declare @d datetime, @d2 datetime2 select @d = '2013-06-05', @d2 = '2013-06-05' select @d, @d2
datetime
返回2013-05-06
(即5月6日), datetime
返回2013-06-05
(即6月5日)。 但是,如果将dateformat
设置为mdy
, @d
和@d2
返回2013-06-05
。
datetime
行为似乎与SET DATEFORMAT
的MSDN文档不一致,该文档指出: 某些string格式(例如ISO 8601)独立于DATEFORMAT设置进行解释 。 显然不是真的!
在这之前,我一直认为yyyy-mm-dd
date是正确的,不pipe语言/语言环境设置如何。
虽然datetime2的 精度有所提高,但某些客户端不支持date , 时间或datetime2,并强制您将其转换为string文字。 具体来说,Microsoft提到了这些数据types的“低级别”ODBC,OLE DB,JDBC和SqlClient问题,并有一个图表显示了每种types如何映射types。
如果数值兼容性超过精度,则使用datetime
根据这篇文章 ,如果你想使用DateTime2具有相同的DateTime精度,你只需要使用DateTime2(3)。 这应该给你相同的精度,占用less一个字节,并提供一个扩大的范围。
几乎所有的答案和评论都是对“利弊”的重视。 以下是所有优点和缺点,以及一些重要的缺点(在下面的#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
types范围的范围(尽pipe如果值在目标types的范围和精度范围内,除了Con#2.1以外,否则错误/舍入将发生,都不需要特殊编码来回转换)。
1.4。 更精确(100纳秒,又称0.000,000,1秒,3.33毫秒又称0.003,33秒)(尽pipe除了例如工程/科学应用程序,额外的精度可能不会被使用)。
1.5。 当被configuration为类似的 (比如Iman Abidi声称的1毫秒不是“相同”(如3.33毫秒))精度为DateTime
,使用较less的空间(7对8字节),但当然,你会失去尽pipe可能是不必要的好处,但可能是两者之一的精确收益(另一个是范围)。
- 缺点:
2.1。 将parameter passing给.NET SqlCommand
,如果您可能正在传递SQL Server DateTime
的范围和/或精度以外的值,则必须指定System.Data.SqlDbType.DateTime2
,因为它缺省为System.Data.SqlDbType.DateTime
。
2.2。 无法隐式/轻松地转换为浮点数字(自min-date-time以来的天数)值,以使用数值和运算符在SQL Serverexpression式中对其执行以下操作:
2.2.1。 增加或减less天数或部分天数。 注意:当需要考虑多个(如果不是所有date时间的)部分时,使用DateAdd
函数作为解决方法并不是微不足道的。
2.2.2。 为了“年龄”计算的目的,取两个date时间之间的差异。 注意:您不能简单地使用SQL Server的DateDiff
函数,因为它不会像大多数人所期望的那样计算age
,因为如果两个date时间跨越指定单位的日历/时钟date – 时间边界,即使对于例如,如果这两个date时间间隔仅为1毫秒,那么DateDiff
将返回1与0(天)之间的差异date时间在不同日历日(即“1999-12-31 23:59:59.9999999”和“2000-01-01 00:00:00.0000000”)。 如果移动相同的1毫秒差异date时间,以便它们不跨越日历date,则将在0(天)的天内返回“DateDiff”。
2.2.3。 通过简单地转换为“浮动”,然后再返回到date时间采取Avg
date时间(在一个聚合查询)。
注意:要将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 “
当然,你也可以先Cast
DateTime
(如果有必要再回到DateTime2
),但是你会失去DateTime2
的精度和范围(全部在1753年之前),而DateTime2
对于DateTime
是最大的,也是最大的同时扩大了最不可能的需要,这引发了一个问题,为什么要使用它,当你失去隐式/简单的转换为浮点数(天数)加/减/“年龄”(与DateDiff
)/ Avg
计算好处是我的经验中的一个很大的收益。
顺便说一下,date时间的Avg
(或至less应该是)是一个重要的用例。 a)除了使用date时间(由于通用的基准date – 时间)来表示持续时间(一种常见做法)之外,还可以获得平均持续时间,b)获取有关平均date的统计信息也很有用,时间在一行/一行的date时间列中。 c)一个标准的(或至less应该是标准的)专门的查询来监视/排除列中可能无效/不再有效和/或可能需要被弃用的值是列出每个值的发生次数和(如果可用)与该值关联的Min
, Avg
和Max
date时间戳。
Select ValidUntil + 1 from Documents
上面的SQL不能用于DateTime2字段。 它返回和错误“操作数types冲突:date时间2与int不兼容”
开发人员join1来获得第二天的日子已经有好几年了。 现在微软有一个超级新的datetime2字段,不能处理这个简单的function。
“我们用这个比老的还差的新型”,我不这么认为!
我只是偶然发现了DATETIME2
一个优点:它避免了Python adodbapi
模块中的一个bug,如果一个标准的库datetime
值被传递,对DATETIME
列有非零微秒,但是如果列被定义为DATETIME2
。
我认为DATETIME2是更好的方式来存储date,因为它比DATETIME更有效率。 在SQL Server 2008中,您可以使用DATETIME2,它存储date和时间,需要6-8个字节来存储,精度为100纳秒。 所以任何需要更高时间精度的人都需要DATETIME2。