1

我的数据库有 3 个表:组织、用户和组织用户连接。OrganizationUserJunction 表跟踪用户所属的组织、他们何时成为该组织的成员以及何时离开该组织。MemberFrom 字段填充了一个已知日期,但 MemberTo 日期一开始是未知的。我不喜欢在我的表中有 NULL 值。

当我处理一个字符串字段时,我可以用“未知”而不是 NULL 填充它们。我想对日期时间列做类似的事情。除了空值之外,还有什么好的策略来处理具有未知值的 SQL Server 日期时间列?

4

6 回答 6

4

以您描述的示例为例。当前成员没有 MemberTo 日期,因此在成员资格表中您不需要 MemberTo 日期。将 MemberTo 日期放在前成员的表中(该表将包含此属性以及与前成员相关的其他属性,但不适用于当前成员)。不需要空值来执行此操作。

于 2013-04-17T09:30:03.080 回答
3

没有其他人提到的另一种方法是为两个日期列使用单独的表。(在重新阅读时,我看到无与伦比的@sqlvogel 确实提到了这一点。我将代码作为示例。如果@sqlvogel 想将它合并到我刚刚赞成的答案中,那对我来说很好。我会之后删除我的答案。)

create table org_users (
  org_id integer not null references organizations (org_id),
  user_id integer not null references users (user_id), 
  member_from date not null default current_date,
  primary key (org_id, user_id, member_from)
);

create table org_users_member_to (
  org_id integer not null, 
  user_id integer not null,
  member_from date not null,
  member_to date not null default current_date
    check (member_to > member_from),
  primary key (org_id, user_id, member_from),
  foreign key (org_id, user_id, member_from) 
    references org_users (org_id, user_id, member_from)
);
于 2013-05-16T10:36:12.207 回答
2

这是一个合理的问题,我不确定你为什么被否决。

至少根据 Joe Celko 的说法,正确答案是使用 9999-12-31 作为您的结束日期。这是根据 ISO 8601 的官方“时间结束”。

您还可以考虑使用为此目的而设计的第 6 范式(又名 Anchor Modeling)。

于 2013-04-16T06:49:40.160 回答
1

有什么问题NULL?如果它的实际原因很NULL重要(例如,心率是NULL因为他死了,或者因为我们还没有捕获它),请在单独的列中跟踪它(可能是一个tinyintFK 到一个名为dbo.DateIsNULLReasonstable 的查找表)。

对此的所有解决方法(“魔术”日期值,对所有日期使用 INT 来查找必须具有NULL有效列或在其中存储魔术日期的不同表)对我来说似乎是黑客行为。

我认为你应该克服你对NULLs的厌恶。它们的存在是有原因的,例如指定值为unknown,无论您喜欢与否,以及无论原因如何。

通过存储UNKNOWN而不是存储可以获得什么NULL?您知道在表和任何二级索引中花费了多少额外空间吗?您现在必须为某些查询过滤掉该场景,您不觉得烦人吗?

于 2013-03-26T18:58:12.940 回答
1

使用默认日期进行会员审核怎么样?加入5年后再说。

或者,如果我们正在与一个商业组织打交道并且您捕获 DOB 和性别,那么您可以计算退休年龄。

我个人认为 NULL 没有问题。在 MemberTo date 的上下文中,IS NULL = 仍然是成员。它与默认值的用途完全相同,并且远没有填充的默认日期值复杂。

于 2013-03-26T19:30:01.293 回答
0

我知道这是一个旧线程,但我偶然发现了它。

这是一个null应该避免的好点,尤其是对于DateTime.

原因:SQL 服务器默认null1/1/1900. 如果您有类似的用例dateOfCasuality,则需要包含特殊逻辑来处理 DOB 相关规则。

可能的解决方案:使用ForeignKey与另一个包含日期的表的关系。但这会增加模式的复杂性。但是,我永远不会尝试将其转换为字符串,因为这会导致编码噩梦。

于 2020-03-15T18:58:47.703 回答