8

我想将部分日期存储在关系数据库(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。

最好的方法是什么?

4

3 回答 3

2

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

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

于 2013-08-29T03:05:31.627 回答
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'作为参数传递,并且您希望获取 year = 2013 和 month = 01 的所有行。因此该where子句将如下所示:

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

在情况(2)中,您传递三个参数 -@Year = 2013, @Month = 1, @Day = null子句where将类似于:

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)

它可能更复杂,具体取决于您要如何处理行。例如,如果您提供参数 like 2013-01,您是否想要获取月份 = null 的行?

另一方面,如果您想传递日期并检查它是否属于日期范围,那么 Gordon Linoff 建议是一个不错的选择。

于 2013-08-29T04:56:12.967 回答
1

根据您指定的内容,您不想使用date_trunc,因为您想要2013-08表示“2013 年 8 月”而不是实际日期!所以你似乎不太关心瞬间,而更多地关心周期

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

2013
2013-08
2013-09-25

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

2013-09-04  |  MONTH

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

再说一次,我的建议你可能会得到一个格式错误的字符串。

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

于 2013-08-29T03:06:55.287 回答