0

我正在设计一个简单的媒体“服务器”作为更大应用程序的一部分。我选择采用与 AWS S3 服务类似的术语,即对象和存储桶(即文件和目录)。

我有两张桌子:

cdn_bucket
id, directory

cdn_object
id, bucket_id, filename, is_deleted

数据库中的其他表可以包含使用外键的对象cdn_object.id。这有很好的副作用,因为我可以指定一个约束来在对象被删除的情况下将字段设置为 NULL(或者如果需要,确实可以防止删除)。例如:

blog_post
id, title, body, featured_image
CONSTRAINT: featured_image = cdn_object.id ON DELETE SET NULL

曾经有人告诉我,我不应该删除任何东西(这是另一篇文章的论据,请不要在这里评论);因此is_deleted国旗。为了澄清这个问题,这就是我所说的“垃圾”,即可恢复的意思。

这很好用,但是我不能利用约束的级联功能(即我将对象标记为已删除,但引用表,例如blog_post.featured_image引用旧 ID)。

我想知道 SO 对以下两种方法的看法可能是什么,或者是否有另一种可能更好的方法。

1.加入cdn_object表

SELECT bp.*, cdno.id featured_image FROM blog_post bp JOIN cdn_object cdno ON cdno.id = bp.featured_image AND cdno.is_deleted = 0.

优点:易于实施。

缺点:每个查询都必须加入cdn_object表。

或者

2.使用垃圾桶

有另一个表,并在删除cdn_object_trash该行时让代码“移动”该行,从而触发所有级联约束。cdn_object

优点:允许关系规则做他们设计做的事情

缺点:设计不好?没有把握。

我的直觉告诉我应该使用该is_deleted标志并相应地编写代码,但这是一个通用类,因此如果我可以在数据库中配置该逻辑,我宁愿不要强迫开发人员每次都编写连接。

我希望我的情况/问题很清楚,如果需要,请让我澄清任何问题。

4

1 回答 1

1

您的第三个选项是设置合理的备份和保留计划,并使用级联删除。虽然我理解“永不删除任何东西”的愿望,但遵守该原则会迫使您在编程选择中变得多余(选项 1)或弄清楚如何构建垃圾表以冗余存储信息(选项 2;你使用数据的字符串表示构建单个表,或者您是否制作模式的垃圾副本?)。这两种选择似乎都需要大量维护(从长远来看)。

我已经使用了这两种选择的变体,如果这些是桌面上唯一的选项,那么选项 1 更容易维护;但是,您必须非常勤奋地使用它,并且您必须确保未来的开发工作符合相同的标准。

于 2013-07-16T22:23:22.927 回答