我应该删除或禁用关系数据库中的一行吗?

发布于 2024-07-09 06:58:51 字数 85 浏览 7 评论 0原文

在一个全新的程序中,空间并不是什么大问题,删除一行或通过布尔值“禁用”禁用一行并让程序忽略它是更好吗?

例如,如果我想从程序中删除用户。

In a brand new program where space isn't really that big a deal, is it better to delete a row or to disable a row by let's say a boolean "Disabled" and have the program just ignore it?

For example, if I wanted to remove a user from a program.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

黯然#的苍凉 2024-07-16 06:58:52

在读了一本关于时态数据库设计的书后,我开始相信这样的理念:每条具有时态意义的记录都需要至少有 4 个时间戳列。 这四个是:创建、删除、开始、结束。 创建和删除的时间戳是相当不言自明的。 您的系统不应该查看在 now() 之前删除的记录。 开始和结束列确定数据何时应用于您的系统。 这是为了保存更改的历史记录。 如果需要更新记录,请将其结束时间设置为 now(),复制该记录,更新副本,并将副本的开始时间设置为 now()。 这样,当您需要查看某件事的历史情况时,您可以让系统弄清楚。 您还可以将开始时间设置为将来的某个时间,以便在那时自动进行更改,或者将结束时间设置为将来的时间,以便在那时自动消失。 将创建/删除的时间戳设置为未来确实没有意义......

After reading a book on temporal database design, I came to believe in the philosophy that every record of temporal significance needs to have at least 4 timestamp columns. Those four are: created, deleted, start, end. The created and deleted timestamps are fairly self-explanatory. Your system shouldn't look at records where deleted is before now(). The start and end columns determine when the data applies to your system. It's for keeping a history of changes. If you need to update a record, you'd set it's end time to now(), copy it, update the copy, and set the copy's start time to now(). That way, when you need to look at the way something was historically, you can have the system figure it out. You could also set the start to some point in the future to have a change take place automatically at that time, or set the end to a future time to have it automatically go away at that time. Setting the created/deleted timestamps to the future doesn't really make sense...

荆棘i 2024-07-16 06:58:52

如果您确实使用了已删除、可见、处于活动等列,则可以通过使用视图来抽象出必须记住使用它的列。

If you do use a deleted, visible, isactive, etc column, you can abstract away having to remember to use it by using views.

孤蝉 2024-07-16 06:58:52

这取决于您和您的要求(当记录存在但不存在时,有些事情会变得相当困难)。

不过,我会说布尔值是一个糟糕的选择。 使其成为可为空的时间戳。 了解某些内容何时被删除非常方便,尤其是当您删除了太多内容并想要撤消部分删除时。

It's up to you and your requirements (some things get rather hard when records exist that...don't).

I will say that a boolean is a bad choice, though. Make it a nullable timestamp. It's pretty handy to know when something was deleted, especially when you deleted too much and want to undo part of the delete.

许一世地老天荒 2024-07-16 06:58:52

这取决于。 如果禁用它,则更容易取消删除/查看某人实际上删除了记录(用于审核)。

您可能还存在不删除记录的技术要求。 例如,如果您想通过仅发送更改的记录来将数据库与其他用户同步,那么如果它实际上被删除,您将无法做到这一点。

It depends. If it is disabled then it is easier to undelete / to see that someone actually deleted the record (for auditing).

You may also have a technical requirement to not delete records. For example, if you wanted to synchronize your database with another user by just sending changed records you wouldn't be able to do that if it was actually deleted.

百合的盛世恋 2024-07-16 06:58:52

您需要将其包含在功能需求中。 如果没有明确说明,您必须自己弄清楚。

在大多数情况下,最好将此类记录存储在单独的表中。 然后,您可以避免一个表引用另一个表的各种情况,并且您需要决定是否也将第二个表中的记录视为已删除。

You need to have it in functional requirements. If it is not said there explicitly you will have to figure out it yourself.

In most cases it is better to store such records in separate table. You then avoid various situations where one table refers another table and you need to decide should records in second table be treated as deleted as well or not.

顾铮苏瑾 2024-07-16 06:58:52

在表中添加“DELETED”列并标记行而不是删除它们会为您带来更多工作,但几乎没有(如果有的话)好处。 现在,每次编写查询时,您都必须记住包含“WHERE DELETED IS NOT NULL”(或其他内容)。

更好的方法是在需要删除数据时删除数据,并依靠定期备份过程来确保不会丢失数据。 如果由于某种原因您需要保留一些已删除的数据(也许用于搜索),您最好将数据复制到为此目的创建的另一个表中,然后删除原始数据。

多年来我继承了许多数据库,不幸的是,这种标记记录而不是删除记录的策略非常常见,并且(至少根据我的经验)总是会导致以后出现重大问题。

Adding a "DELETED" column to your table and marking rows instead of deleting them creates a lot more work for you with little (if any) benefit. Now, every time you write a query you have to remember to include "WHERE DELETED IS NOT NULL" (or whatever).

A better approach is to delete data when you need to delete data, and rely on your regular backup process to ensure that no data is ever lost. If for some reason you need to keep some deleted data handy (for searches, maybe), you're better off just copying the data to a different table created for this purpose and then deleting the originals.

I've inherited many databases over the years, and this strategy of flagging records instead of deleting them is unfortunately very common, and (in my experience at least) always leads to major problems down the road.

看海 2024-07-16 06:58:52

如果您有时需要删除的数据,但不是经常需要:您可以将记录移动到单独的数据库/表中(例如usersusers_deleted,或者更好的 somedb.userssomedb_deleted.users)。

这样,数据仍然可以通过查询访问(尽管它不会像普通查询那么简单),但它不会使原始数据库混乱,并且您不必围绕它进行编码。

If you will need the deleted data sometimes, but not very often: you can move the records into a separate database/table (e.g. users and users_deleted, or better somedb.users and somedb_deleted.users).

This way, the data is still accessible through a query (although it won't be as simple as the normal one), yet it doesn't clutter the original database and you don't have to code around it.

遗弃M 2024-07-16 06:58:52

除非您有管理自己删除的特定需要,否则最好只删除行。

Unless you have a specific need for managing your own deletions, you are better off just deleting the rows.

桜花祭 2024-07-16 06:58:52

我想指出的是,(在大多数国家/地区)在某些用例中,由于法律原因您无法删除记录。 当然取决于行业和数据。

在这种情况下,我认为最佳实践指南是对“已删除”数据进行影子表,这将为您带来实际删除的好处 由 MatthewMartin 概述,通过扩展,我发现这种模式通常比在数据中创建“活动”位标志更可取-桌子。

I'd like to note that there are (in most countries) use-cases where you can't delete records for legal reasons. Industry and data dependant of course.

In this case I believe the best practice guidleine is to shadow table the "deleted" data which gains you the benefits of actual deletion outlined by MatthewMartin and by extension I have come to find this pattern frequently preferable to creating "active" bit-flags across my data-tables.

贪了杯 2024-07-16 06:58:52

这应该根据应用需求来确定。 我两种方式都做到了。 我有一些应用程序需要支持撤消,因为删除行的成本以及由此引起的级联删除成本太高,无法支持撤消。 不过,通常情况下,我所做的应用程序需要用户确认删除,然后按照用户的要求进行操作。 在某些情况下,出于隐私考虑,您必须删除数据。 也就是说,如果用户请求删除,您需要真正将其删除,而不仅仅是将其标记为非当前。 在其他情况下(例如与税务相关的交易),可能有理由将数据保留在非当前状态,直到法律不再要求为止。 我有适合这两个类别的应用程序。

在需要保留“存档”数据的情况下,可以使用各种策略。 根据是否需要立即可用,您可以将其推送到保留或定期备份和清理的归档表。 如果需要撤消,您可能希望将其保留在当前表中,并通过设置标志来标记它。 这实际上取决于您的架构的复杂性、应用程序的要求以及在某种程度上的个人偏好。

This should be determined by the application needs. I have done it both ways. I have some applications that need to support undo as the cost of removing a row -- and the cascading deletes that are caused by that -- are too expensive to not have it. Normally, though, the applications I have done require the user to confirm deletes, then just do as the user has asked. In some cases, you must delete the data due to privacy concerns. That is, if the user requests to be removed, you need to really remove it, not just mark it as not current. In other cases (like tax-related transactions), there may be reasons to keep data in a non-current state until no longer required by law. I have applications that fit in both categories.

Various strategies can be used in the case where you need to keep "archival" data. Depending on whether it needs to be immediately available you can push it to archive tables that are either kept or backed up and cleaned out regularly. If there is a need for undo you may want to keep it in the current table and just mark it by setting a flag. It really depends on the complexity of your schema, the requirements of the application, and personal preference to some extent.

酒中人 2024-07-16 06:58:52

我正在创建 CRUD,并且面临同样的问题。

解决办法:CRUD的D应该disable而不是delete。

问题

  • “每个”查询都应检查注册表是否已禁用(例如 flag=1)。 更具体地说,无论何时 select * 都应该检查这一点。
  • 默认情况下,每次插入都应激活注册表(flag=1)。
  • 更新不应更改标志。
  • 禁用是变相更新,标记flag=0。

大问题

  • 垃圾收集器。 存在三种策略:删除旧注册表、删除未引用的注册表或混合策略。

I am creating a CRUD and i'm facing the same problem.

Solution : The D of CRUD should disable instead of delete.

Problems:

  • "Every" query should check if the registry is disable or not (flag=1 for example). More specifically, ever select * should check that.
  • Every insert should activate the registry (flag=1) by default.
  • Update shouldn't change the flag.
  • Disable is an update in disguise that marks the flag=0.

Big Problem

  • Garbage collector. Exists three strategies : to delete old registries, to delete registries that are not referenced or a mix of strategies.
菊凝晚露 2024-07-16 06:58:52

这是一个判断调用,但我最终在我之前认为可以删除行的表上添加了“禁用”列。 我想说大多数时候添加禁用列会更安全。 然而,对于 n:n 关系来说,这可能会变得棘手,所以这是需要考虑的事情。

It's a judgment call, but I have ended up adding "disabled" columns on tables where I previously thought I could just delete row. I'd say most of the time you're safer adding a disabled column. This can get tricky with n:n relations however, so that's something to consider.

我只土不豪 2024-07-16 06:58:52

最好添加“已删除”列并让用户取消删除或清除已删除的项目。

It's probably best to add "deleted" column and offer users to undelete or purge deleted items.

呆橘 2024-07-16 06:58:52

这取决于数据库的功能。 它是所有真理的来源吗? 如果是,则禁用而不是删除,因为更容易从不良操作(即用户错误)中恢复。 如果数据库是从某个上游数据源提供的,请删除未使用的数据。 任何娱乐/恢复都可以由上游系统完成。

It depends on the function of the database. Is it the source of all truth? If yes, then disable rather than delete, as it is easier to recover from bad operations (ie user error). If the database is feed from some upstream data source, delete then unused data. Any recreation/recovery can be done by the upstream system.

缪败 2024-07-16 06:58:52

正如许多人已经说过的那样,应用程序的需求决定了您想要做什么。 但对我来说,标记一行似乎没有使用正确的工具来做正确的事情。 从逻辑上讲,我们将删除视为删除,因此,如果由于法律原因不允许您删除,那么您首先就不会删除它。
同时,我考虑了所有内部数据结构的保存和索引。 更不用说检索数据时可以进行的所有优化,但添加检查(在视图或查询中)会随着数据库的复杂性和实体之间的关系呈指数级影响性能。

简单来说,就是把删除逻辑放在UI层,防止用户出错,给应该删除的用户删除权限。 使用定期备份来保存档案。 如果您的应用程序绝对需要严格的审核历史记录,请在触发器中实现它并将审核放入异地数据库中,以避免生产中的所有流量、检查和垃圾。

As many have already said, the application needs dictated what you want to do. But to me, marking a row seems like not using the right tool for the right thing. We logically think of a delete as a DELETE, so when if you are not allowed to delete for legal reasons, then you don't delete it in the first place.
At the same time, i think about all the internal data structure keeping and indexing. Not to mention all the optimizations that can be done to retrieve data, but adding that check(in the view or in the query) affects the performance exponentially with the complexity of the database and the relations the entities have.

In a nutshell, put the deletion logic in the UI layer to prevent user errors and give delete permissions to users who should be able to delete it. Use regular backups for keeping archives. If your application absolutely requires a strict audit history, implement it in triggers and put the audit in an off-site database to avoid all that traffic, check and crap from the production.

明媚如初 2024-07-16 06:58:52

对于这个问题,还有两种我常用的解决方案。 我同意其他人的观点,他们认为这确实符合您的数据要求。

如果使用外键约束会导致引用完整性问题,您可以阻止用户删除记录(前提是您的 RDBMS 支持)。 有几次,我向最终用户提供了一条消息:“在取消与 <父对象> 的关联之前,您无法删除此 <对象>”。 只要您预计不会与另一个或多个其他表存在大量关联,此方法就可以发挥作用。

另一种方法是将任何取消关联的记录移动到与未删除的记录关联。 例如,假设您有一门课程与 10 个单独的课程时间相关联。 如果删除课程,您可以允许用户决定是否删除所有 10 个课程,或者它们是否与新课程或现有课程关联。

There are two additional solutions for this which I have commonly used. I agree with other individuals who have posted that it is really up to the requirements of your data.

You could prevent the user from deleting the record if it will cause referential integrity problems by using foreign key constraints (provided your RDBMS supports that). A few times I have provided a message to the end-user that "You cannot delete this <object> until you disassociate <parent object> with it." This can work as long as you don't anticipate there are a tremendously high number of associations with another other table or tables.

Another approach is to move any disassociated records to be associated with a record that isn't deleted. For example, say you have a course for which 10 separate class times are associated with it. If you delete the course, you could allow to the user to decided if all 10 classes are deleted or if they are associated with a new or existing course.

在风中等你 2024-07-16 06:58:51

不删除将为所有未来的查询创建一类新的错误。 不要忘记,查询编写通常是由高级用户(即非 IT 专业人员)和初级开发人员完成的。 因此,现在每个包含仅由 BIT 活动标志标记的无效数据的表都需要在 WHERE 子句中为从现在到永远的每个查询添加一个附加 AND。 这将帮助用户陷入失败的深渊,而不是成功的深渊。 然而,我强烈鼓励您无论如何实现这些标志系统,因为如果没有糟糕的设计,维护开发人员就不需要修复它会产生的大量错误。

表中的历史数据有多大价值? 如果业务具有前瞻性,那么表中的旧数据可能会成为一种负担——它会在创建约束时引起问题(必须修改所有约束以排除您希望不存在的数据)。 数据质量保证变得很复杂,因为必须不断地重新识别什么是“我们害怕删除但永远不想再次使用或更新的旧垃圾”和我们关心的新东西。

是因为失误而被删除吗? 如果该行对应于现实生活中的实体,那么保留并设置“蒸发”、“死亡”、“离开建筑物”标志也许会很有趣。 如果您不小心插入了与现实生活中没有实体对应的行,则 DELETE 并不是一件坏事。 将从未存在过的假想客户保留在客户表中重要吗?

最后,个性起着重要作用。 人们也可以成为数据迷。 如果 DBA 保留 30 年前的所有报纸并且不喜欢删除数据,也许他应该确保根据优点而不是不相关的个​​人偏好做出数据设计决策。

Not deleting will create a new class of bugs for all future queries. Don't forget that query writing is often done by power users (i.e. non-IT professionals), and junior developers. So now every table that has invalid data marked only by a BIT active flag will need an additional AND in the WHERE clause for every query from now until forever. This will help users fall into the pit of failure instead of the pit of success. However, I strongly encourage you to implement these flag systems anyhow because without bad design, there is no need for maintenance developers to fix the numerous bugs it will create.

How valuable is it to have historical data in the table? If the business if forward looking, having old data in the tables can just be a burden-- it cause problems when creating constraints (all constraints will have to be modified to exclude data you wish wasn't there). Data quality assurance is complicated by having to continually re-identify what is "old crap we are afraid to delete but never want to ever use or update again" and new stuff we care about.

Is it being deleted because it was a mistake? If the row corresponds to an entity in real life, maybe it is interesting to keep and set a "vaporized", "dead", "left the building" flag. If you accidentally inserted a row that corresponds to no entity in real life, a DELETE is not a bad thing. Are imaginary customers that never existed important to keep in the customer table?

And finally, personality plays a big role. People can be packrats with data, too. If a DBA keeps all his newspapers from 30 years back and don't like deleting data, maybe he should make sure he's making data design decisions based on the merits and not an irrelevant personal preference.

善良天后 2024-07-16 06:58:51

这取决于。 (但我确信你已经猜到了。)

在实践中,违反此处的正确用法几乎总是导致删除。

删除的主要不良后果是,当父记录消失时,其他表中的依赖记录的引用完整性会丢失。

用于捍卫删除的一个红鲱鱼(您已经通过忽略存储容量问题正确处理了这一问题),期望它会对查询效率产生任何明显的影响。

在很多情况下,用户或软件问题导致某人需要点击大“撤消”按钮; 如果你删除了,你就不走运了(至少不会得到特别的帮助,也不会激怒你宁愿友善的人。)

我通常使用的术语是“活跃”和“不活跃”。


还有几点需要考虑(作者:Totophil):

  1. 删除某些数据库中的记录不会自动释放磁盘空间。
  2. 清除不再需要的任何敏感信息有助于避免安全风险。
  3. 数据保护立法可能要求您的组织在某些情况下清除有关个人的任何可识别信息。 各国的立法有所不同,一些提示:

  4. 另一方面,法律可能要求您保留某些信息。

It depends. (But you guessed that already, I'm sure.)

In practice, the violation of proper usage here is almost always in the direction of deleting.

The main bad consequence of deleting is how often there are dependent records in other tables whose referential integrity is lost when the parent record goes away.

One red herring used to defend deletion (which you've already dealt with properly by dismissing the issue of storage capacity), is expecting that it will make any noticeable difference in query efficiency.

There are too many cases where user or software issues cause someone to need to hit the big "Undo" button; if you delete, you're out of luck (at least without getting special help and aggravating people you'd rather be nice to.)

The terminology I usually use is "Active" and "Inactive".


A few more points to consider (by Totophil):

  1. Deleting a record in some databases will not automatically free up the disk space.
  2. Purging any sensitive information that you no longer require helps avoiding security risks.
  3. Data protection legislation might require your organisation under certain circumstances to purge any identifiable information about an individual. The legislation differs from country to country, some pointers:

  4. On the other hand you might be required by law to keep certain information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文