在数据库中存储部分日期

时间:2013-08-29 02:58:54

标签: sql database-design schema

我想在关系数据库(MySQL,PostgreSQL等)中存储部分日期。例如,输入可能只是年份(2013年);年和月(2013-08);或年,月,日(2013-08-29)。我不能只使用正常的DATE类型,因为年份将扩展到2013-01-01,这与年,月和日无法区分。

我想到要么将日期分成三个单独的字段(年,月,日作为整数),但我在DBS中丢失所有日期细节,并且必须管理更多的指标。

我的另一个想法是将它存储为DATE,并有另一个专栏说明日期的精确程度。例如,“2013-08-01”和“月份”表示日期仅精确到月份(2013-08)。 '2013-08-01'和'day'表示日期完全是2013-08-01。

最好的方法是什么?

3 个答案:

答案 0 :(得分:2)

也许最好的方法是将这些视为时间跨度并拥有effdateenddate。您可以表示您想要的任何时间跨度。一年就像'2012-01-01'和'2012-12-31'。单个日期将类似于“2013-08-28”和“2013-08-28”。

这也使您可以灵活地扩展表示以处理季度或其他时间组。

答案 1 :(得分:2)

我认为有两种可能的方法:

(1)存储日期的子字符串,例如:

'2013'               -- year 2013 
'2013-01'            -- year 2013, January
'2013-01-01'         -- year 2013, January 1

(2)存储 3个不同的列,年,月,日(您可以构建索引年+月+日期,没有问题)

2013  null  null     -- year 2013 
2013     1  null     -- year 2013, January
2013     1     1     -- year 2013, January 1st

哪一个最好取决于您想如何查询数据。假设您有存储过程,并且您希望传递一个参数以使所有行都进入条件状态。

如果(1),您将字符串@Date = '2013-01'作为参数传递,并且您希望获取年份= 2013和月份= 01的所有行。因此where条款就像:

where left(Date, len(@Date)) = @Date

如果(2),则传递三个参数 - @Year = 2013, @Month = 1, @Day = nullwhere子句类似于:

where
    Year = @Year and -- Supposing @Year is always not null
    (@Month is null or @Month is not null and Month = @Month) and
    (@Day is null or @Day is not null and Day = @Day)

可能会更复杂,具体取决于您希望如何处理行。例如,如果您提供类似2013-01的参数,是否要获取其中month = null的行?

另一方面,如果你想通过日期并检查它是否属于日期范围,那么Gordon Linoff建议是一个很好用的建议。

答案 2 :(得分:1)

根据您的指定,您不希望使用date_trunc,因为您希望2013-08表示“2013年8月”,而不是实际日期!因此,您似乎不太关心瞬间,而更多关注期间

我认为你应该存储字符串。如果您存储:

2013
2013-08
2013-09-25

作为字符串你应该没问题。他们排序很好。另外,您只需要一列。如果您使用两列,您的数据可能看起来很有趣。例如,如果您存储

2013-09-04  |  MONTH

有人可能想知道为什么4存在。

然后,根据我的建议,你可能会收到格式错误的字符串。

另一个想法是制作你的字符串ISO 8601 Time intervals。您的数据库系统甚至可能具有时间间隔类型。