这是在数据库表中实现取消属性的最佳方式,前提是少于 3% 的行被取消。
对于取消的数据,我想存储附加信息
- 通过谁
- 什么时候
- 为什么
在大约 95% 的查询中,我只想选择未取消的行。
此外,我希望能够对未取消列的某些列实施唯一约束。
在某些列中使用 NULL 作为未取消指标的优缺点是什么?
这是在数据库表中实现取消属性的最佳方式,前提是少于 3% 的行被取消。
对于取消的数据,我想存储附加信息
在大约 95% 的查询中,我只想选择未取消的行。
此外,我希望能够对未取消列的某些列实施唯一约束。
在某些列中使用 NULL 作为未取消指标的优缺点是什么?
我不确定我喜欢
NULL
没有被取消。我想我宁愿有一个默认为 1 的 Active 标志,并在某些事情被取消时设置为 0。现在您的检查只是 WHERE active = 1 或 WHERE active = 0,而不是处理所有的OR IS NULL
orOR IS NOT NULL
检查,并且如果该模型成熟为其他原因,除了“取消”之外,一行可能因其他原因而处于非活动状态。如果您使用的是 SQL Server 2008+,则可以使用过滤索引来使一种类型或另一种类型的查询稍微高效一些。NULL
意味着未知,在你只有两个状态的情况下,“未取消”不是未知。至于谁,为什么,什么时候?也许这完全是一个单独的表,并且可以像审计日志一样工作(包括实体是否被标记为已取消,然后再次激活,然后再次取消,等等)。它会是这样的:
您有 97% 的活动行和这 97% 的 95% 的查询。
选择 97% 的行的 WHERE 子句不会得到索引的帮助:它的选择性不够
我会为您的“事物”考虑 2 个表:ThingActive 和 ThingCancelled
对于查询取消行的 5%,您可以只读取 Canceled 表或 UNION/View
对此的一个转折...
取消的表仅存储主表 ID 和额外的列(因此它不存在以查找活动)。
如果“少于 3% 的行被取消”,这可能无关紧要。- 让他们扫描?
甲骨文:
对于唯一约束,如果您
cancelled_seq
在索引中包含(来自序列),则取消的行将永远不会导致约束失败亲:如果您对该列进行索引,则可以快速扫描已取消的行,因为索引中将省略所有s 的行
null
缺点:默默无闻
这真的非常取决于我们正在谈论的数据。
但是,我个人不喜欢使用 NULL 来指示状态(除非它是外键或类似的东西)。我更喜欢默认值为零的整数,使用零作为表示尚未取消的方式。
我的推理:如果您决定稍后添加另一个“状态”,您将不得不实现复杂的逻辑,而不仅仅是递增整数。
另一种选择是您可以创建第二个(几乎是重复的)表,其中包含这些额外的行。当 a 被取消时,将它移到那个“cancelled_”表中。当然,这是假设您的原始表格只有很少的列。否则,我的标准化本能开始发挥作用。
或者,您可以创建一个“取消”表,将取消的数据与外键引用一起保存回主表。但同样,这完全取决于您的数据和环境。