2009-02-04 40 views
10

在SQL Server 2005中存储旧日期(1753之前)的最佳/最有效的方式是什么?我不关心存储时间 - 只是日期。 SQL Server的日期时间数据类型只能保存日期为1753年1月1日.MSDN文档指出有date和datetime2数据类型,但SQL Server Management Studio似乎不支持它们(错误:无效的数据类型)。在SQL Server中存储旧日期的最佳方法

将日期存储为“YYYYMMDD”形式的字符串或整数效率如何?我对表格中的两个日期字段(StartDate和EndDate)进行了大量查询和排序。

UPDATE:

目前已在不同的领域下面存储年份,月份和日期的建议。将部件存储在不同字段而不是单个整数字段中的好处是什么?

+0

使用3个整数而不是1代表的优点是您无需计算CodeMonkey1提议的天数。这比听起来更难。 – Treb 2009-02-05 11:19:41

+0

这些日期涉及什么?您可能[需要考虑公历与儒略日历问题](http://stackoverflow.com/questions/3310569/what-is-the-significance-of-1-1-1753-in-sql-server/3310588#3310588 ) – 2010-10-03 12:27:43

回答

15

date类型肯定是你想使用的。它的范围是“1月1日,1日至9999年12月31日A.D.”它也只是存储日期信息,没有时间部分。

您或许正在使用SSMS 2005而不是2008或连接到2005实例吗?这种类型是introduced in SQL Server 2008。如果你有能力使用2008年的数据库,那么我认为这无疑是一条可行的路。

4

我从来没有这样做过,但也许你可以将日期存储为一个整数,表示自从最低日期适合你以来的天数。然后,您可以创建一个将这些整数映射到年,月和日的查找表,也可以编写用户定义的函数将整数转换为日期,反之亦然。

这应该是相当有效的选择和排序方面。

4

字符串可能会比仅存储年份,月份和日期的整数效率低。在你的查询中这有点多余,但是它们的运行速度可能会更快,因为你可以以对你正在进行的查询有意义的方式对它们进行索引。

因此,例如:

CREATE TABLE myOldDates (
    year INT, 
    month INT, 
    day INT, 
    -- otherstuff ... 
) 

然后查询都将是这样的:

-- get records between 5/15/1752 and 3/19/1754 
SELECT * FROM myOldDates 
    WHERE 
    (year = 1752 AND ((month = 5 and day >= 15) or month > 5) OR year > 1752) 
    AND (year = 1754 AND ((month = 3 and day <= 19) or month < 3) OR year < 1754) 

这是丑陋的,可以肯定的,但这就是丑,因为它得到的范围查询,所以一旦你第一次写它,你可以将它封装在一个函数中。

1

以YYYYMMDD格式存储日期的一个问题是,最后可能会存在不存在的日期(例如16000231 - 2月31日不存在)。在进入数据库之前,你需要做一些验证客户端。

Ian Varley所提出的,在年,月和日整数中存储日期的情况也是如此。但是,我喜欢他的回答,只是希望我能想到它;-)

+0

每个正确的客户端对从任何外部来源收到的数据做了什么? :) (提示:验证它) – Esko 2009-02-04 16:12:56

1

YYYYMMDD = 8字节。您可以使用3列将其缩减为4个字节,使用SMALLINT和TINYINT。

1

按照CodeMonkey1的建议使用整数似乎是个不错的主意,它会使“数学计算”变得更容易(例如,某个日期+ XX天)。

写一些UDFs(也可以通过CodeMonkey1的建议)来转换int - > YYYYMMDD - > int并且您将拥有Ian Varley在答案中提到的灵活性。

1

一个想法 - 如果你有一些.NET的知识,你可以创建一个CLR类型来存储日期,这本质上是一个日期时间。如果您使用日期而不是简单查询进行大量计算,则可能需要进行调查

相关问题