我的数据库有3个表:Organization,User和OrganizationUserJunction。 OrganizationUserJunction表跟踪用户所属的组织,用户何时成为组织的成员以及何时离开组织。 MemberFrom字段填充了一个已知日期,但最初不知道MemberTo日期。我不喜欢表中包含NULL值。
当我处理一个字符串字段时,我可以用'UNKNOWN'而不是NULL填充它们。我想对datetime列做类似的事情。除了null以外,还有什么好方法可以处理具有未知值的SQL Server datetime列?
如何使用默认日期进行成员审核。加入后说5年。
或者,如果我们与一家商业组织打交道,并且您捕获了DOB和性别,那么您可以计算退休年龄。
我个人没有看到NULL问题。在MemberTo日期的上下文中,IS NULL =仍然是成员。它的用途与默认值完全相同,并且比填充的默认日期值复杂得多。
以您描述的示例为例。当前成员没有MemberTo日期,因此在成员资格表中,您不需要MemberTo日期。将MemberTo日期放在前成员表中(该表将包含此成员以及与前成员相关联的其他属性,不适用于当前成员)。为此,无需任何null。
没有其他人提到的替代方法是为两个日期列使用单独的表。 (在重新阅读时,我看到独特的@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)
);
这是一个合理的问题,我不确定您为什么被否决。
至少根据Joe Celko的说法,正确的答案是使用9999-12-31作为您的endDate。这是根据ISO 8601的正式“时间限”。
您也可以考虑使用为此目的而设计的第六范式(也称为锚定模型)。
NULL
怎么了?如果NULL
的实际原因很重要(例如,由于他死了或因为我们尚未捕获它,心率NULL
就很重要),请在单独的列中进行跟踪(也许tinyint
FK会查找表称为dbo.DateIsNULLReasons
表)。
所有解决方法(“不可思议”的日期值,对于所有查询都使用INT来查找必须具有NULL
able列或在其中存储魔术日期的不同表的所有日期,请使用INTs)对我来说似乎是黑客。
我认为您应该克服对NULL
的厌恶。它们的存在是有原因的,例如指定值是unknown
,无论您是否喜欢它,并且无论原因如何。
[通过存储UNKNOWN
而不是NULL
有什么好处?您知道表和任何二级索引中会花费多少额外的空间吗?您现在是否必须为某些查询过滤该方案,这是否使您感到烦恼?
我知道这是一个旧线程,但是我偶然发现了它。
避免使用null
是一个好主意,尤其是对于DateTime
。
原因:SQL Server默认将null
设置为类似1/1/1900
。如果您有dateOfCasuality
之类的用例,则需要包括特殊逻辑来处理与DOB相关的规则。
可能的解决方案:将ForeignKey
关系与另一个包含日期的表一起使用。但这将增加架构的复杂性。但是,我绝不会尝试将其转换为字符串,因为这会导致编码梦night。