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 等其他表作为单独的表可能更有意义,因为有多个数据点不适用于某些设备。
检查约束很好,应该在可能的情况下使用,但总有一些时候需要一个过程。