在很多数据库中我似乎都在工作这些天我不能仅仅出于多种原因删除记录,包括以后可以稍后显示它们(比如不再存在的产品)或者只是保持历史。
所以我的问题是如何最好地使记录失效。
我经常添加一个date_expired
列,即datetime字段。通常我会查询date_expired = 0
或date_expired = 0 OR date_expired > NOW()
的位置,具体取决于数据将来是否过期。与此类似,我还添加了一个字段调用expired_flag
。当此值设置为true / 1时,记录将被视为已过期。这可能是最简单的方法,尽管您需要记住在任何时候只需要当前项目时包含expire子句。
我看到的另一种方法是将记录移动到存档表,但是当存在大量需要历史表的表时,这会变得非常混乱。它还使得值(例如国家/地区)的检索更加困难,因为您必须首先执行左连接(例如),然后执行第二次查询以查找实际值(或使用修改后的左连接重做查询)。
另一个选项,我没有看过,也没有完全尝试过我自己就是有一个表,其中包含来自所有过期记录的所有数据或某种形式的数据 - 某种历史表。在这种情况下,检索将更加困难,因为您可能需要搜索大型表,然后解析数据。
是否有更好的其他解决方案或修改?
我正在使用MySQL(使用PHP),所以我不知道其他数据库是否有更好的方法来处理这个问题。
答案 0 :(得分:3)
我更喜欢日期过期的字段方法。但是,有时两个日期(初始日期和日期都已过期)很有用。因为如果数据可以过期,那么知道它何时处于活动状态通常很有用,这也意味着它也知道它何时开始存在。
答案 1 :(得分:2)
如果查询速度对您很重要,我喜欢date_expired选项上的expired_flag选项。
答案 2 :(得分:1)
我认为添加date_expired
列是最简单且侵入性最小的方法。只要您的INSERTS和SELECTS使用显式列列表(如果它们不是,则它们应该是这样),那么对您现有的CRUD操作没有任何影响。在date_expired
列上添加索引,开发人员可以将其作为属性添加到依赖于现有表中数据的任何类或逻辑。总而言之,努力的最大价值。我同意,相比之下,其他方法(即归档表)最多也很麻烦。
答案 3 :(得分:1)
我通常不喜欢数据库触发器,因为它们会导致奇怪的“幕后”行为,但是在删除时触发将待删除的数据插入到历史表中可能是一种选择
根据我的经验,我们通常只使用“Active”位,或者像你提到的“DateExpired”日期时间。这非常有效,并且很容易处理和查询。
这里有一个相关的帖子提供了一些其他选项。也许CDC选项?
答案 4 :(得分:1)
我还建议添加一个“状态”列,该列与您正在使用的代码中的枚举类型相匹配。删除列上的索引,您将能够通过where子句非常轻松有效地缩小返回的数据范围。
根据您的需要,可以使用一些可能的枚举值:
将列设置为tinyint(即SQL Server ......不确定MySQL等价物)。如果愿意,您还可以使用键/值对和表之间的外键约束来设置匹配的查找表。
答案 5 :(得分:1)
我一直使用ValidFrom
,ValidTo
方法,其中每个表都有这两个附加字段。如果ValidTo Is Null or > Now()
,那么您知道自己拥有有效记录。通过这种方式,您还可以在数据生效之前将数据添加到表中。
答案 6 :(得分:0)
我的表通常有一些字段:creation_date,last_modification,last_modifier(fk to user),is_active(布尔值或数字,取决于数据库)。
答案 7 :(得分:0)
查看“慢慢变化的维度”SCD算法。数据仓库世界有多种选择适用于此处。
没有“最好” - 每个都响应不同的要求。
这是一个整洁的总结。
类型1 :新记录会替换原始记录。没有旧记录的痕迹。
类型2 :新记录将添加到客户维度表中。要区分所需的“有效日期范围”列对。它有助于“此记录是当前的”标志。
类型3 :修改原始记录以反映更改。
如果您搜索“慢慢改变尺寸”,您可以阅读更多相关信息。
答案 8 :(得分:-1)
Oracle针对此问题的一个非常好的方法是partitions。我不认为MySQL有类似的东西。