我将编写一些代码来管理我的应用程序中已删除的项目,但我将软删除它们,以便在需要时将其返回。在隐藏或删除项目时,我的应用程序逻辑中有一个层次结构。
我逻辑上将我的物品放在三个容器中,分别是国家,城市,地区和品牌。 每个项目应属于一个国家,一个城市,一个区域和一个品牌。 现在,如果我删除了一个国家/地区,则应删除属于指定国家/地区的城市,地区,品牌和商品。如果我删除了城市,它也应该删除它下面的所有东西(地区,品牌等)
A Note
当我删除某个国家/地区并删除相关品牌时,我应该注意一个品牌可能包含多个国家/地区的商品。
你建议
将项目(无论是国家,城市,项目等)标记为已删除,每次从数据库加载任何项目时都需要检查大量代码,如果已删除或未删除一些额外的字段用于标记其所属的城市是否已删除,并且其所属的国家/地区将被删除等等。
将已删除的内容分别移至特定表格(DeletedCountries,Deleted Cities等) 并保存与之关联的项目的ID,以便稍后将其插回到原始表格中。当然,这将保存我的应用程序所有代码,这些代码将设法检查所有已删除的项目并确保删除所有层次结构。
也许你对实现这样的事情有更好的方法/建议/想法!
答案 0 :(得分:4)
为了论证,解决方案#2(将已删除的项目移动到他们自己的表中)的一个优点是,如果您有大量的记录,则不必担心索引记录的“已删除”状态。
话虽如此,如果我要从表到表“移动”数据(通过删除然后插入),我会确保在1个事务中执行此操作。
答案 1 :(得分:4)
我正在使用一种技术,我们在数据库中的每个用户维护表上存储'DeleteDate'。 DeleteDate字段是smalldatetime数据类型,默认值为6/1/2079
与DeleteDate字段的索引相结合,我们可以使用标准的View或User-Defined-Function来仅返回“当前”记录(即将来具有删除日期的记录)。在查找当前数据时,所有查询都会遍历此索引,并且删除将成为一个简单的更新查询。
需要对相关表进行一些额外的逻辑检查。但这是不必担心用户“意外”删除有价值数据的代价的一部分。
将来,当这些表格过大且存在大量已删除的记录时,我们可以先在DeleteDate上对表格进行分区。这将使所有“已删除”的记录远离“实时”记录。
答案 2 :(得分:1)
将项目标记为删除确实使信息检索变得复杂,而且,您需要自己处理级联删除。
我会选择“邮箱”方法,即将删除的记录移到不同的表格中。我做了一个使用软删除的项目,最后我将所有删除调用放到存储过程中,并在存储过程中处理副本和删除。
答案 3 :(得分:1)
您应该通过将所有子项标记为已删除来管理层次结构。这种方式,如果你的例如。产品属于某个品牌,只有在品牌被删除时才能查看。您还应该将您的逻辑放在数据检索端,以避免不必要地收集已删除的信息。
SELECT
*
FROM
products p,
category c
WHERE
p.catId = c.Id
AND NOT c.Deleted
最重要的是,有关已删除类别的信息应编入索引。
CREATE PRIMARY INDEX ON category (Id)
CREATE INDEX ON category (Deleted)
或
CREATE INDEX ON category (Id, Deleted)
答案 4 :(得分:0)
我认为标记该项目是最好的方法,甚至我也使用邮件方法进行软删除。
是的,需要很多东西来考虑管理,但我没有找到任何其他方式。我只是在每个表中添加一个额外的列,该表是状态,其数据类型为bit。
由于
答案 5 :(得分:0)
您要求的删除技术有多复杂?
只有一个日期字段且没有审核日志,您可以拥有即时删除标记。如果datefield为null,则表示尚未删除。然后,您可以在索引上使用该日期字段(如果索引允许空值)。
如果你想要更复杂的东西,那么你可以使用额外的表格。您是否允许删除,取消删除,重新删除并保留每个记录?如果是这样,请为操作记录保留一个单独的表,并仅保留一个带有布尔字段的记录(实际上该表上的连接可能更快,取决于数据)
答案 6 :(得分:0)
如果您经常重新设置项目,标记是一种更好的方法,但您最终必须更改数据访问权限以避免显示标记的项目,如果您已经设置了大量代码,这可能会非常痛苦访问您的数据,如果您有大量“遗留”代码访问数据,那么移动可能会更好。如果它很少,并且您也对历史记录日志感兴趣,那么移动到另一个数据库表也可以正常工作。
实现其中一种方法的一种简单方法是使用更改删除行并执行操作的触发器。但是,如果您确实需要删除项目,则在标记而不是移动项目时,标记选项将成为皇家PITA。在许多情况下触发器更容易的原因是您捕获每个删除,而不仅仅是那些由代码启动的删除。