在数据库的整数列中,使用`null`还是`-1`来表示“无限”更好?

4
我经常在我的数据库中有存储“数字或无限”的字段。例如,maxFileSizemaxUsers等。应该可以设置最大值,也可以完全不限制。
目前我有时使用null表示“无限/没有限制”,有时使用-1
我想知道使用其中一个的原因是否存在。据记录,我使用的是PHP / MySQL / Doctrine / Symfony。
编辑:
我不是在征求意见,而是相关于-1null的事实(如已给出的答案)。这些可能包括速度、查询复杂性、数据库大小等等。

如果您决定开始存储负值,会发生什么?现在,一些非无限的值将被任意检测为无穷大。 - Basic
2
个人而言,我会使用一个大数来避免所有的无穷测试。 - Cerad
@Cerad 好吧,那我就不需要测试无限大了,但在某些情况下我需要测试这个大数字(例如当我想显示maxFileSize时,我需要进行如下检查:if (maxFileSize == bigNumber) then echo "unlimited size"; else echo maxFileSize;)。 - Christian
4个回答

5

如果您要使用整数来存储一个值,并且想要存储一个非常大的值,则可以使用 2,147,483,647。这是您可以放入该字段的最大值,因此它接近于该字段允许的无限大。

-1 和 NULL 都存在问题。例如,可能尚未设置该值。这似乎比表示某些任意值更合理的用途是使用 NULL。而使用特殊值需要复杂的逻辑:

where users < maxusers or maxusers is null
where users < maxusers or maxusers = -1

这种专门的逻辑使查询更难优化。如果您使用字段可以存储的最大值,则不会出现此问题。
顺便说一下,我在数字方面很少遇到这个问题,但在日期方面非常普遍。通常,在慢变维度表中,“结束日期”将是诸如“9999-01-01”或“4195-01-01”的内容。它们代表着一个远未来的任意时间点。而且,它们通常比使用NULL更容易进行优化。

这是最佳方法。“无限”本来就不现实。如果有人确实试图上传2,147,483,647 MB的文件,那么你面临的问题比“规格应该允许上传无限大的文件”要更大。 - Erik
@Erik 好的,对于 maxFileSize 来说,“无限大”并没有太多意义,但是对于像 maxUsers 这样的东西来说,在我看来确实有意义。 - Christian
你的数据库也没有足够的空间来存储无限数量的用户。 - Erik

1
你也可以选择在数据库中使用两个字段来实现结果:
file_quota int NOT NULL DEFAULT 50000,
file_quote_is_limited boolean NOT NULL DEFAULT true

有几种方法可以在MySQL中存储boolean values,这当然会影响数据库大小,具体取决于与仅存储无限制的NULL相比较的规模。但是,这种技术有一些优点:

  • 即使您没有记录 NULL 表示无限制,但是看到映射更清楚明白了什么意思。(考虑新开发人员等)
  • 在您的代码中很难找到 if (null == $obj->getFileQuota()) { 或类似结构。这些片段通常不易维护。
  • 查询复杂性取决于您想要实现什么,但这两个字段不会增加意外的复杂性。事实上,它使理解正在发生的事情变得更容易:
    where file_quota < 50000 or file_quota is null
    vs.
    where file_quota < 50000 or ! file_quota_is_limited(否定取决于您选择的数据类型来映射布尔值,但Doctrine应该会处理)
  • 如果您的代码中出现 $usage = $usedFiles / $user->getFileQuota();,您甚至可以通过适当约束数据库列来避免除以零。
  • 您可以进一步扩展您的逻辑以映射更多状态。

1

只是我的个人观点

null - 在许多情况下,任何框架或查询都期望它作为空值或未定义的值。但是,如果您尝试使用-1或其他任何值,则一些查询函数SUM(),AVG()等可能会因此值而出现错误。

所以我认为没有理由养成坏习惯。null就是null,每个人都知道null可以存在于表中,表示为空或未定义。

如果您使用-1,那就意味着不为空已定义,对我来说这就是完全相反的值。

你能问一下我们是否可以使用1替代0true替代false吗?

如果您的值被定义且不为空-您可以使用任何您想要的内容。

如果您的值未定义和/或上下文是值为空,我建议不要使用等于null的内容。


0

在这里使用NULL表示“没有限制”是非常合理的。使用实际的整数值很可能会导致问题。

像-1这样的“魔法数字”一开始看起来无害,但最终可能变得相关,这意味着您需要一个新的、更神奇的数字来替换它。

这使得定义minmax的边界变得容易,可以将它们设置为NULL,而不是使用任意大或小的值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接