我为每条记录都有StartDate和EndDate。在这两个字段中使用时,我应该给NULL特殊含义吗?

时间:2009-02-12 18:58:11

标签: sql database-design

所以,我有一个表,其中StartDate和EndDate用于确定记录的活跃性。我想过使用NULL来减轻维护者不得不为某些记录制作一些疯狂的日期。例如,如果在EndDate中使用NULL时将NULL定义为正无限,则数据维护者不需要为长期记录提供1-1-2100之类的内容。

我可以自己推测一些权衡:定义NULL作为无穷大意味着更清晰的数据和消除定期维护工作,但它也意味着更长的查询和存储过程。所以我想知道你们现实世界中的人们如何权衡这一点。

编辑:意见大约有一半。如果我已经澄清StartDate和EndDate仅用于确定where子句中记录的活动性,并且从未出现在选择列表中,那么是否会使比例倾斜?我需要阅读的一个主题可能是索引。 Thanks'all。

11 个答案:

答案 0 :(得分:4)

如果您的记录的StartDateEndDateNULL,则表明以下情况:

BETWEEN StartDate AND EndDate

永远不会匹配此记录。

您需要执行以下操作:

BETWEEN IFNULL(StartDate, '01.01.1000') AND IFNULL(EndDate, '01.01.3000')

,当然,这对指数不利。

当然,你可以创建一个基于函数的索引,但无论如何你都需要为它提供一个常量。

摘要:如果你想要性能,请使用常量,不要使用NULL

答案 1 :(得分:3)

NULL已经有了含义,将NULL的解释添加为有效数据值会导致歧义。运行查询并返回数据时,结果为NULL的含义是什么?如何区分失败状态和有效的Max状态?

定义最小和最大常量,并将Null设为Null。

好评:
@ Haoest - 你是对的Null与一组Null不一样,我不清楚。处理Null时SQL的行为需要更多代码才能进行更多检查。找到Null时SQL的结果可能与程序员的直觉NULL(SQL)不匹配 @ MBCook - 很棒的链接,希望我自己发布了 - 谢谢

更新:一旦查询或函数具有该日期的Null,您就不再知道Null是否已分配,因为它意味着Max或因为Null在查询中向上传播。

答案 2 :(得分:2)

我之前为此目的使用了NULL,没有任何问题,但我没有开发任何大型应用程序。

答案 3 :(得分:1)

在这种情况下,我肯定会使用null。存储过程和查询不是什么大不了的事。

如果你有像'2100-01-01'那样的值,那么只要看一下,我就会认为它是一个有效值。如果我看到NULL,我认为它具有特殊含义(除了缺乏价值,虽然有时候,这就是它的全部,并且那很好)。

答案 4 :(得分:1)

我倾向于使用定义的最小和最大日期而不是空值。主要是因为,至少在C#中,当你从数据库中获取数据时,你必须开始处理Nullable类型,我发现这很烦人。

它还可以使查询更容易。如果我查询结束日期为Max,那么我会得到所有日期的最大结束日期,以及结束日期小于max的所有日期,这通常是我想要的。如果我有空值,那么我必须进行连接以获得小于max和null值的日期。希望有道理。

我想,至关重要的是,我从开发人员的可用性角度处理这些问题,而不是数据库用户,所以这就是我的观点所在。

答案 5 :(得分:1)

我想说你自己的推测是完全正确的。这真是其中一种权衡类型的情况。

我自己的人偏好是在日期类型字段中禁止NULL,并且总是使用“高值”来表示结束日期。对我来说,这大大简化了我必须对开始/结束日期进行的所有查询,并防止我在多个查询中进行大量的NULL检查。

那说,这取决于应用程序。如果我在日期字段中必须有NULL,我会使用它们,但如果我能用一个真实的日期代替,我会的。当然,使用实际日期的缺点是它只是一个真正的日期,并且不再具有NULL的标准数据库定义,即缺席数据。

答案 6 :(得分:1)

我尽可能尝试使用NULL值。

我对EndDate列中的NULL的理解是,到目前为止还没有定义结束日期。这与该记录从开始日期到结束日期有效是一致的。

我同意Quassnoi你不能直接指定

BETWEEN StartDate AND EndDate

但是不是他的建议(这使得使用索引/索引变得困难),这个也是有效的:

(somedate >= StartDate or StartDate is null)
AND
(somedate <= EndDate or EndDate is null)

AFAIK这将允许使用索引,但检查执行计划以了解您的具体情况。

使用“特殊”开始/结束日期的缺点是可执行性。如果您的所有数据库访问都是通过具有或多或少强制库的特定程序语言进行的,那么您可以将其工作。但是,如果您有不同的访问路径(直接SQL,不同的语言/库),这将很难做到。

可能有第三种方法:对DML语句使用NULL,然后将触发器更改为预定义的最小/最大值。那么选择可能会更容易。但是使用触发器会打开另一种蠕虫...

我的结论:这种情况对数据库NULL来说是一个不错的选择。根据我的经验,我还没有遇到严重的性能问题。但我同意额外的NULL处理有点令人讨厌。

答案 7 :(得分:0)

我认为使用null比某些任意特殊值更好。如果没有别的,看到空值会让你停下来想想它可能意味着什么。

答案 8 :(得分:0)

如果您确实使用“结束日期”字段的默认“系统”日期(甚至是“开始日期”字段),请确保在代码中的某个位置记录这些日期的含义(以及可能的数据库架构)。它将使那些追随你的人更容易理解其他任意日期的含义。

答案 9 :(得分:0)

如果您在数据库中使用NULL日期,请确保使用DateTime? (在您的代码中可以为空的C#),这将使您的生活更轻松:)

答案 10 :(得分:0)

在数据库中使用NULL日期。使用DateTime?在你的C#代码中。

避免使用魔法值。