我正在设计一个简单的媒体“服务器”作为更大的应用程序的一部分。我选择采用与AWS S3服务类似的术语,即对象和存储桶(即文件和目录)。
我有两张桌子:
cdn_bucket
id, directory
和
cdn_object
id, bucket_id, filename, is_deleted
数据库中的其他表可以包含使用cdn_object.id
上的外键的对象。这有很好的副作用,因为我可以指定一个约束来在删除对象的情况下将字段设置为NULL(或者确实在需要时阻止删除)。 e.g:
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
。Pro:易于实施。
Con:每个查询都必须加入
cdn_object
表。
或
2。使用垃圾桌
拥有另一个表
cdn_object_trash
,并在删除行时将代码“移动”到行cdn_object
,从而触发所有级联约束。Pro:允许关系规则执行他们设计的目标
骗局:设计不好?不确定。
我的直觉告诉我应该使用is_deleted
标志并相应地编写代码,但这是一个通用类,所以如果我可以配置,我宁愿不强迫开发人员每次都写入连接DB中的逻辑。
我希望我的情况/问题很清楚,如果需要,请让我澄清任何要点。
答案 0 :(得分:1)
您的第三个选择是设置合理的备份和保留计划,并使用级联删除。虽然我理解“从不删除任何内容”的愿望,但遵守该原则会迫使您在编程选择(选项1)中多余,或者弄清楚如何构建垃圾表以冗余存储信息(选项2;你是否使用数据的字符串表示构建单个表,还是制作模式的垃圾副本?)。这两种选择似乎都需要维护很多工作(长期来看)。
我使用过这两种选择的变体,如果这些是桌子上的唯一选项,选项1更容易维护;但是,您必须非常勤奋地使用它,并且必须确保未来的开发工作符合相同的标准。