如果我将日期时间作为浮点数存储在数据库中,有什么可以咬我的?

时间:2009-05-27 21:12:18

标签: sql-server datetime

如果我将日期时间作为浮点数存储在数据库中,有什么可以咬我的?我有一个很好的理由这样做,所以不要抱怨:)

编辑:我正在考虑将转换(float,@ thedate)存储在浮点列中。

10 个答案:

答案 0 :(得分:7)

什么能咬你?第一个浮点数不是一个精确的数据类型,因此可能永远不会用于任何需要精度的东西。接下来,float不会自动拒绝错误的日期。接下来,如果要执行任何日期函数,首先必须将数据转换回日期时间数据类型,这会浪费服务器资源。

你说你有充分的理由想要这样做,但是有了可能是什么的线索,我提出日期应该存储在用于处理它们的数据类型中。

答案 1 :(得分:4)

艾伦说,加上......维护的根本问题;当其他人进入项目,并在DB中看到日期时间的浮动,并试图对它做错了,或尝试将其重构为正确的类型,或者只是花费数小时仔细查看代码以找出哎呀。整个维护问题在某种程度上可以通过广泛记录正在发生的事情以及你为什么这样做而得到缓解,我建议高度推荐。

答案 2 :(得分:4)

这是一篇关于“揭开SQL Server DATETIME数据类型的神秘面纱”的好文章

http://www.sql-server-performance.com/articles/dev/datetime_datatype_p1.aspx

从阅读中看,看起来datetime存储为2个4字节的整数或者你可以使用二进制(8)

正如其他人所说的那样,存储浮动会导致你失去一些精确度。

答案 3 :(得分:1)

一个人的精确损失。缺乏决议是另一回事。

这是一个小问题,但浮点版本IEEE 754与VAX浮点。

答案 4 :(得分:1)

SQLite使用一种时间格式(少数可用的一种)和一个(64位)双浮点,使用整数部分作为纪元以来的天数,而小数部分作为一天的一小部分。它似乎运作良好。

请参阅SQLite Date and Time Functions“格式12是表示为浮点值的Julian日数。”

使用Julian Dates 15位十进制数字可以获得几千年的毫秒精度。

根据this Julian Date Converter,JD 9999999.99999为CE 22666 12月20日11:59:59.1 UT星期四

答案 5 :(得分:1)

你失去了一些精确度。我在SQL Server中测试过:

select getdate(), cast(getdate() as float), cast(cast(getdate() as float) as datetime)

您可以查看是否重复运行此操作,转换时可能会丢失4毫秒。如果您的数据库支持像smalldatetime这样的数据类型,并且您只需要精确到秒,那么您可以消除这种差异。

答案 6 :(得分:0)

如果你要将这些数据存储为浮点数,我认为你最好存储秒数,因为epoch作为浮点数而不是作为浮点数的datetime

答案 7 :(得分:0)

实际上,据我所知,MSSQL和Oracle实际上在内部存储日期时间为浮点数(日期和小数天)

select cast(0 as datetime), cast(0.5 as datetime)
1900-01-01 00:00:00.000 1900-01-01 12:00:00.000

答案 8 :(得分:0)

无论精确度如何 - 取决于您选择的起点数,您可能会遇到比较问题。

如果您无法为每个日期时间创建精确浮点数,则可能还有两个日期时间,如果它们解析为不同的浮点数,则会同时比较这两种方式。

答案 9 :(得分:0)

使用浮动的潜在缺点是您将失去使用系统内置日期操作功能的能力。如果您只进行间隔计算,浮点数可能没问题,但与日历相关的任何内容都可能需要进行一些轮重新发明。

顺便说一下,似乎Oracle至少使用固定字段作为其内部日期表示:

select
  to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') as Date_Value,
  dump(sysdate) as Internals
from dual;

DATE_VALUE          INTERNALS                                                   
------------------- ------------------------------------------------------------
2009-05-28 09:51:12 Typ=13 Len=8: 217,7,5,28,9,51,12,0                          
1 row selected