Database 如何在数据库中表示时间的结束?

Database 如何在数据库中表示时间的结束?,database,database-design,time,32bit-64bit,Database,Database Design,Time,32bit 64bit,我想知道如何在数据库中表示时间结束(正无穷大)值 当我们使用32位时间值时,最明显的答案是实际的32位时间结束-接近年份。 现在我们使用的是64位时间值,我们不能在DATETIME字段中表示64位的时间结束,因为 由于SQL Server和Oracle(我们两个受支持的平台)都允许使用长达9999年的时间,我想我们可以选择一些“大”的未来日期,比如1/1/3000 然而,由于客户和我们的质量保证部门都会查看数据库值,我希望它是明显的,而不是像有人弄乱了他们的日期算法 我们只是选择一个日期并坚持它

我想知道如何在数据库中表示时间结束(正无穷大)值

当我们使用32位时间值时,最明显的答案是实际的32位时间结束-接近年份。
现在我们使用的是64位时间值,我们不能在DATETIME字段中表示64位的时间结束,因为

由于SQL Server和Oracle(我们两个受支持的平台)都允许使用长达9999年的时间,我想我们可以选择一些“大”的未来日期,比如1/1/3000 然而,由于客户和我们的质量保证部门都会查看数据库值,我希望它是明显的,而不是像有人弄乱了他们的日期算法


我们只是选择一个日期并坚持它吗?

我们有时会选择一个日期,然后制定一项政策,规定该日期不得未经过滤。执行这一政策最常见的地方是中间层。我们只是过滤结果,将“神奇”的时间结束日期更改为更令人愉快的日期。

不要让日期变得“特别”。虽然你的代码不太可能出现在9999年甚至2^63-1年,但看看几年前使用“12/31/1999”带来的所有乐趣吧


如果您需要发出“无止境”或“无限”时间的信号,则添加一个布尔/位字段来表示该状态。

使用最大排序日期,根据您的DBMS,该日期可能为9999-12-31。您希望这样做,因为如果您尝试采用“纯粹主义”方法(如某些评论员所建议的使用Null或Marc B所建议的使用永久标志),则基于日期范围的查询将很快变得极其复杂

当您在日期范围中使用max collating date表示“永远”或“直到另行通知”时,它可以实现非常简单、自然的查询。这使得此类查询非常清晰和简单:

  • 查找截至给定时间点有效的记录。
    。。。其中生效日期=@PointInTime
  • 查找在以下时间范围内有效的记录。
    。。。其中生效日期=@EndOfRange
  • 查找日期范围重叠的记录。
    。。。其中,PostgreSQL中的A.effective_date为“无穷大”。它还支持“-infinity”。值“infinity”保证晚于所有其他时间戳

    create table infinite_time (
      ts timestamp primary key
    );
    
    insert into infinite_time values
    (current_timestamp),
    ('infinity');
    
    select *
    from infinite_time
    order by ts;
    
    2011-11-06 08:16:22.078
    infinity
    
    PostgreSQL至少从8.0版开始就支持“infinity”和“-infinity”

    通过使用dbms支持的最长日期,您至少可以部分模拟这种行为。但最长日期可能不是最佳选择。PostgreSQL的最大时间戳是294276年的某个时间,这肯定会让一些人感到惊讶。(我不想让用户感到惊讶。)

    这样的值可能更有用:“9999-12-31 11:59:59.999”

    2011-11-06 08:16:21.734
    9999-12-31 11:59:59.999
    infinity
    

    这不是9999年的最大值,但数字排列得很好。您可以将该值包装在无穷大()函数和
    createdomain
    语句中。如果您从源代码构建或维护数据库结构,则可以使用宏扩展将
    无限
    扩展到合适的值。

    表示“直到永恒”或“直到进一步通知”的概念是一个不确定的命题

    关系理论认为不存在null,因此必须将任何表分成两部分:一部分是已知结束日期/结束时间的行,另一部分是未知结束时间的行

    但是(就像有一个空值)将表一分为二也会给查询编写带来混乱。视图在某种程度上可以容纳只读部分,但无论如何,更新(或在视图上写入而不是在视图上写入)都将是困难的,并且可能会对性能产生负面影响

    将null表示为“结束时间未知”将使更新变得“更容易”,但读取查询会因所有情况而变得混乱。。。或合并。。。你需要的构造

    使用dportas提到的理论上正确的解决方案,在所有这些情况下,如果您想从日期时间中“提取”日期,就会变得很混乱。如果当前的DATETIME值是“结束(可表示的)时间(如您所说,从现在起数十亿年)”,那么这不仅仅是对该DATETIME值调用日期提取器函数的简单情况,因为您还希望该日期提取器为您的案例生成“可表示日期的结束”

    另外,您可能不希望在用户界面中将“缺席时间结束”显示为值9999-12-31。因此,如果您在数据库中使用时间结束时的“真实值”,您将面临一些工作,以确保该值不会出现在您的UI中的任何地方


    很抱歉,我不能说有一种方法可以避免一切麻烦。你唯一的选择就是把事情弄得一团糟。

    NULL表示“没有日期”,这是一个不同的概念。NULL有效。。然后始终将其查询为更适合宗教的NVL(mydate,sysdate+1)。stackexchange.com?使用您使用的数据类型支持的最大日期。不要使用null,因为这在任何查询中都不太可能有意义。实际上,如果它是“结束日期”列,null在概念上可能有意义——但与不可能的大值相比,它使任何查询复杂化。这种“乐趣”并不是因为选择了某个值。“乐趣”是因为当这些“乐趣”系统建成时,人们对这些系统在选定的日期是否仍能运行做出了(错误的)判断。此外,所有类型都是有限的(是的,甚至Java的大整数也是有限的,因为没有无限的内存),因此每个系统中的每个有序类型都有一个“特殊”值,它是所有类型中最高的可表示性。溢出问题不会仅出现在6位COBOL日期字段上。我朋友的录像机固件在2005年10月也有自己的Y2K问题。+1是第一个提到过滤屏幕的
    2011-11-06 08:16:21.734
    9999-12-31 11:59:59.999
    infinity