The*_*uad 2 null database-design constraint stored-procedures
这个问题是关于 NULL 的正确使用和对业务逻辑与存储过程的 CHECK 约束的使用。
我有以下表格设置。

我对表进行了标准化以避免使用 NULL。问题是这些表中的一些由于业务流程而相互依赖。有些设备必须经过消毒,有些设备在另一个系统中进行跟踪。所有设备最终都将在处置表中处置。
问题是我需要执行检查,例如如果布尔字段RequiresSantization为真,则在DisposalDate输入Sanitize字段之前无法输入。
此外,如果布尔值为IsTrackedInOther真,则OfficialOutOfService必须先输入字段,然后DisposalDate才能输入。
如果我将所有这些列合并到Archive.Device表中,那么我将拥有 NULL 字段,但我将能够使用 CHECK 约束管理所有业务规则。
另一种方法是让表保持原样,并通过从表中选择以检查记录是否存在,然后抛出适当的错误来管理存储过程中的业务逻辑。
这是可以适当使用 NULL 的情况吗?布尔领域IsTrackedInOther
和RequiresSanitization基本赋予意义的NULL字段。如果IsTrackedInOther是,false则设备未在其他系统中跟踪SectionID并且SpecialDeviceCode为 NULL,我知道它们应该为 NULL,因为它未在其他系统中跟踪。同样,OfficialOutOfServiceDate和OOSLogPath我知道会是NULL藏汉,并且DisposalDate可以随时进入。
如果IsTrackedInOther是true,那么SectionID和SpecialDeviceCode将是必需的,如果OfficialOutOfServiceDate和OOSLogPath是NULL,那么我知道它们还没有被正式从该系统中删除,因此DisposalDate在输入它们之前不能有a 。
所以这是一个问题
单独的表/无 NULL/在存储过程中强制执行规则
对比
在 CHECK 约束中组合表/NULLs/强制规则。
我知道在图片中使用 NULL 进行查询可能很复杂并且有一些未定义的行为,因此从这个意义上讲,单独的表和存储过程似乎是有益的。或者,能够使用 CHECK 约束并将规则内置到表中似乎同样有益。
有什么想法吗?谢谢阅读。请在需要时要求澄清。
如果它们被合并并且我允许 NULL,则更新示例表。
* = Allow NULL
+-------------------------+
|Archive.Device Table |
+-------------------------+
|DeviceID |
|SerialNumber |
|DeviceTypeID |
|IsTrackedInOther |
|SectionID* |
|SpecialDeviceCode* |
|OfficialOutOfServiceDate*|
|OOSLogPath* |
|OOSRemarks* |
|RequiresSanitization |
|SanitizeMethodID* |
|SanitizeLogPath* |
|SanitizeDate* |
|SanitizeRemarks* |
|Location |
|OriginalInventoryDate |
|ArchiveDate |
|LastUpdated |
|ReasonID |
|StorageLocation |
|ArchiveRemarks |
|CategoryCode |
+-------------------------+
Run Code Online (Sandbox Code Playgroud)
示例检查:
IsTrackedInOther = 0 AND SectionID IS NULL AND SpecialDeviceCode IS NULL AND
OfficialOutOfServiceDate IS NULL AND OOSLogPath IS NULL AND OOSRemarks IS NULL
OR IsTrackedInOther = 1 AND SectionID IS NOT NULL AND SpecialDeviceCode IS NOT NULL
Run Code Online (Sandbox Code Playgroud)
这似乎是处理这个问题的自然方法,还是设计问题?
查询可以包含空值的列比查询不能包含空值的列更复杂。查询多个表也比查询一个表更复杂。我不会让避免空驱动规范化。
例如,您提到所有设备最终都会被处置并获得处置日期。如果 Disposal 表中没有其他列,那么在我看来,将 DisposalDate 放在 Device 表中更有意义。Sanitize 等其他表作为单独的表可能更有意义,因为有多个数据点不适用于某些设备。
检查约束很好,应该在可能的情况下使用,但总有一些时候需要一个过程。