3

我正在寻找一个数据库来保存关于一组图片的元数据,我想要的一个字段是拍摄日期。我希望能够以粗略或细粒度的精度存储它,例如对于数码图片,精确到秒的时间戳将可用,但我希望能够将图片标记为在特定的年份,甚至是特定的十年(十年是我会去的最粗略的十年)拍摄,并且能够以这种方式搜索,例如请求所有 90 年代的照片,或所有 1992 年的照片或所有照片某一天的照片等

我想知道是否有一种内置的方法可以用 SQL 做到这一点,或者是否有另一种更好的方法。我考虑过分解日期并分别存储每个部分,例如有十年字段、一年字段、一个月字段等,但这似乎是一种有点笨拙的做事方式。

只要是免费的,我就不会担心我使用哪种 SQL 技术。我现在正在看H2。

4

3 回答 3

3

对于准确日期的模糊搜索,您不需要单独存储每个部分。您可以调整 where 子句。对于 2012 年的所有内容:

SELECT * FROM yourtable
WHERE yourtime >= '2012-01-01' AND yourtime < '2013-01-01'

如果你想要一个特定的日子:

SELECT * FROM yourtable
WHERE yourtime >= '2012-07-28' AND yourtime < '2012-07-29'

或特定时间:

SELECT * FROM yourtable
WHERE yourtime >= '2012-07-28 13:00:00' AND yourtime < '2012-07-28 14:00:00'

为了使所有这些查询高效,您可以向时间戳列添加索引。


关于如何存储模糊日期,一种选择是有一个日期范围:

id    taken_from            taken_to               title
1     2011-01-01 00:00:00   2012-01-01 00:00:00    a pic of my car last year

对于模糊日期的模糊搜索,您可以执行以下操作:

模糊日期搜索

在伪 SQL 中:

SELECT
    *,
    (LEAST(@to, taken_to) - GREATEST(@from, taken_from)) /
    (GREATEST(@to - taken_to) - LEAST(@from, taken_from)) AS relevancy
FROM yourtable
WHERE taken_to >= @from AND taken_from < @to

您可能希望按相关性进行排序,并且您可能希望包括其他因素,例如某些搜索词的全文搜索返回的相关性。

于 2012-07-28T21:58:54.593 回答
3

你可以只用两列来做到这一点:一列用于时间戳,另一列用于精度级别。然后你必须定义一个精度比例,以及一些标准来在时间戳上编码较低精度的日期。

例如,精度标度可以是:

0   full timestamp
1   day
2   month
3   year
4   decade

有了它,您可以像这样存储日期:

timestamp                 |  precision   | notes
--------------------------+--------------+---------------------
2012-07-05 14:00:00       |  0           | full precision
--------------------------+--------------+---------------------
2012-07-05 00:00:00       |  1           | precision up to day
--------------------------+--------------+---------------------
2012-07-01 00:00:00       |  2           | month and year
--------------------------+--------------+---------------------
2012-01-01 00:00:00       |  3           | year
--------------------------+--------------+---------------------
2010-01-01 00:00:00       |  4           | decade
--------------------------+--------------+---------------------
于 2012-07-28T22:10:45.177 回答
1

我过去使用过 CHAR 和 VARCHAR,用问号或破折号替换缺失的部分。问号表示“未知”,破折号表示“不适用”。事实证明,这对于用户(复杂诉讼中的秘书和律师助理)来说足够直观,对于律师来说足够灵活,并且分类合理。

确实意味着您的“日期”不再是 SQL 日期。也就是说,日期/时间算术和间隔兼容性在它完全有效的情况下的鲁棒性要低得多。(什么是“1960 年代加上 20 天?”是更长的十年,还是变化的十年?)这是否重要取决于应用程序。我认为这对您的应用程序来说不是问题。

详细信息和注意事项在dba.stackexchange.com上

于 2012-07-28T22:47:35.313 回答