在数据库中存储日期

时间:2017-01-16 11:24:13

标签: mysql sql datetime period

我想讨论最好的"数据库中存储日期的方法。我们来谈谈SQL / MySQL,但这个问题可能适用于任何数据库。我感觉多年来我做错了什么......

在英语中,我的信息是:

-In year 2014, value is 1000
-In year 2015, value is 2000
-In year 2016, there is no value
-In year 2017 (and go on), value is 3000

有人可能会存储为:

BeginDate   EndDate     Value
2014-01-01  2014-12-31  1000
2015-01-01  2015-12-31  2000
2017-01-01  NULL        3000

其他人可以存储为:

Date        Value
2014-01-01  1000
2015-01-01  2000
2016-01-01  NULL
2017-01-01  3000
  • 第一种方法验证规则看起来像是为了避免漏洞和重叠而开发的混乱。
  • 在第二种方法中,问题似乎过滤了一段时间内的一个准时日期。

我的同事更喜欢什么?还有其他建议吗?

编辑:我仅使用全年,例如,我的数据通常会随着日期粒度而变化。

编辑2:我考虑使用存储"日期" as" BeginDate",按日期排序,然后选择" EndDate"在下一行(或上一行)中。存储" BeginDate"和"间隔"会导致孔/重叠问题作为方法一,我需要一个复杂的验证规则来避免。

1 个答案:

答案 0 :(得分:0)

这主要取决于您使用此信息的方式 - 我假设您所做的不仅仅是在数据库中存储一年的值。

这里有很多猜测,但我猜你有其他表格有时间限制的数据,你需要比较日期以找到匹配。

例如,在您当前的架构中:

select *
from other_table ot
inner join year_table yt on ot.transaction_date between yt.year_start and yt.year_end

这应该是一个简单的优化查询 - 它是一个直接的数据比较,如果表足够大,你可以添加索引来加速它。

在你的第二个架构建议中,它并不那么容易:

select *
from other_table ot
inner join year_table yt 
 on ot.transaction_date between yt.year_start 
 and yt.year_start + INTERVAL 1 YEAR

至关重要 - 这更难以优化,因为每次比较都需要执行标量函数。它可能并不重要 - 但是对于大型表或更复杂的查询,它可能是一个瓶颈。

您还可以将年份存储为整数(正如某些评论者推荐的那样)。

select *
from other_table ot
inner join year_table yt on year(ot.transaction_date) = yt.year

再次 - 这可能会对性能产生影响,因为每次比较都需要执行一个函数。

我的纯粹主义者不喜欢将其存储为整数 - 所以你也可以使用MySQL的YEAR datatype

因此,假设数据大小不是您要优化的问题,那么解决方案实际上就在于此表中的数据与模式的其余部分相关的方式。