我认为我不是唯一一个对此疑惑的人。关于数据库行为,您通常练习什么?您喜欢物理删除数据库中的记录还是更好地使用“已删除”标志或布尔列来表示记录是活动的还是非活动的?
这绝对取决于数据库的实际内容。如果您使用它来存储会话信息,请在会话过期(或关闭)时立即清除它,您不想让垃圾留在那里。因为它实际上不能再用于任何实际用途。
基本上,你需要问自己的问题是,我是否需要恢复这些信息?就像 SO 上被删除的问题一样,它们应该被标记为删除,因为我们正在积极允许撤消。我们还可以选择将其显示给特定用户,而不需要额外的工作。
如果您不积极寻求完全恢复数据,但仍想保留它以供监视(或类似)用途。我建议您尽可能了解一种聚合方案,并将其转移到另一个表中。这将使您的主要表格不会被删除的数据污染,并使您的次要表格针对监视目的(或您所想象的任何其他目的)进行优化。
有关时间数据,请参见:http://talentedmonkeys.wordpress.com/2010/05/15/temporal-data-in-a-relational-database/。
使用删除标志的优点:
- You can get the data back later if you need it,
- Delete operation (updating the flag) is probably quicker than really deleting it
使用删除标志的缺点:
- It is very easy to miss
AND DeletedFlag = N
somewhere in your SQL - Slower for the database to find the rows that you are interested in amongst all the crap
- Eventually, you ll probably want to really delete it anyway (assuming your system is successful. What about when that record is 10 years old and it was "deleted" 4 minutes after originally created)
- It can make it impossible to use a natural key. You may have one or more deleted rows with the natural key and a real row wanting to use that same natural key.
- There may be legal/compliance reasons why you are meant to actually delete data.
作为对所有帖子的补充…
然而,如果您计划标记记录,最好考虑为活跃记录创建视图。这将使您免于在SQL查询中编写或忘记标志。如果您认为这也有用途,可以考虑为非活跃记录创建视图。
我很高兴找到这个帖子。我也好奇大家对这个问题的看法。我已经在许多系统上实施“标记为已删除”大约15年了。每当用户打电话说意外删除了某些东西时,标记为未删除肯定比重新创建或从备份中恢复要容易得多。
我们正在使用PostgreSQL和Ruby on Rails,看起来我们可以有两种方法来实现这个,修改Rails或添加ondelete trigger并使用pl / pgsql函数标记为已删除。我倾向于后者。
关于性能影响,我们将会对具有少量删除项目和具有许多删除项目的大型表进行EXPLAIN-ANALYZE的结果感到兴趣。
在使用一段时间的系统中,我发现新用户往往会做一些愚蠢的事情,例如意外删除文件。因此,当人们刚接触某个职位时,他们具有之前担任该职位的人的所有访问权限,但却没有任何经验。意外删除某些东西并能够快速恢复会使每个人能够快速重新开始工作。
但正如有人所说,有时您可能因某种原因需要取回特定的密钥,在这种情况下,您需要真正删除它,然后重新创建记录(在撤消删除并修改记录)。
我将它们标记为已删除,但并没有真正删除。但是,我偶尔会清除所有垃圾并将其存档,以防影响性能。 (Wǒ jiāng tāmen biāozhù wèi yǐ shānchú, dàn bìng méiyǒu zhēnzhèng shānchú. Dànshì, wǒ ǒuci ài huì qīngchú suǒyǒu jiānkè huò bìng jiǎng qí cún'àn, yǐ fáng yǐngxiǎng xìngnéng.)
如果涉及个人数据,那么无论如何都会涉及法律问题。我认为这在很大程度上取决于你所在的地方(或数据库所在的地方)以及使用条款是什么。
在某些情况下,人们可以要求从您的系统中删除,这种情况下需要进行硬删除(或至少清除所有个人信息)。
如果涉及个人信息,我会建议您在采取任何策略之前与您的法律部门核实。
如果您担心“休眠”记录会减慢数据库访问速度,您可能希望将这些行移动到另一个充当“存档”表的表中。
对于用户输入/管理的数据,我使用了您描述的标记方法,并给用户提供了“清空回收站”界面,以便他们删除项目。
我有一个具有许多依赖关系的数据库。因此,我无法删除一些记录,因为其他数据仍然依赖于它。这是我通常做的事情;我尝试删除数据,如果可以正常运行,我知道它没有任何依赖性,也没有关系。如果无法删除,则会捕获错误并将其标记为非活动状态:
try
{
_context.SomeTable.Remove(someEntity);
await _context.SaveChangesAsync();
}
catch (DbUpdateException ex) when (ex.InnerException is SqlException && (ex.InnerException as SqlException).Number == 547)
{
// Mark as inactive
someEntity.Active = false;
await _context.SaveChangesAsync();
}
- winforms
- combobox
- fogbugz
- java
- date
- internationalization
- asp.net
- iis
- url-rewriting
- urlrewriter
- c#
- enums
- ocaml
- haxe
- algorithm
- string
- viewstate
- .net
- c++
- c
- symbol-table
- mysql
- database
- postgresql
- licensing
- migration
- vb.net
- vb6
- declaration
- vb6-migration
- python
- psycopg2
- backup
- vmware
- virtualization
- gnu-screen
- authentication
- desktop
- excel
- xll
- cultureinfo
- regioninfo
- oracle
- client
- session
- download
- html
- virtual
- constructor
- scenarios
- perl
- full-text-search
- javascript
- ajax
- testing
- oop
- inheritance
- vim
- encapsulation
- information-hiding