我正在设计一个简单的媒体“服务器”作为更大的应用程序的一部分。我选择采用与AWS S3服务类似的术语,即Objects和Buckets(即文件和目录)。什么是可以“被丢弃”的对象的合适的桌子设计
我有两个表:
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
。专业:易于实施。
Con:每个查询都必须加入
cdn_object
表。
或
2.使用垃圾表
有另一个表,
cdn_object_trash
,并让代码“搬家”的行cdn_object
当它删除,引发所有级联约束。临:允许关系规则做他们的目的是做
缺点:不好的设计?不确定。
我的直觉告诉我,我应该使用is_deleted
标志并编写相应的代码,但是这是一个通用类,所以我宁愿不强迫开发者编写的参加每一次,如果我可以配置数据库中的逻辑。
我希望我的情况/问题很明确,如有需要,请让我澄清任何问题。
谢谢你,你碰到了头脑 - 我希望尽可能容易为未来[不勤奋]开发者写查询;而且我知道他们不会做得很好。我倾向于选项2,垃圾表有效地作为对象表的副本。在课堂上写几条额外的句子来处理这个问题*我认为*是一个可以接受的折中方案? – HelloPablo
我的理论家对此妥协不寒而栗,因为它最终会引导您制作数据库中每个表的重复副本。您需要决定如何以及为什么要传输数据,以及如何锁定数据,以便人们不会在临时或未来的开发中使用它。 –
我认为这是可行的,如果您的桌子数量有限,并且您有远见建立一些维护功能(滚出比特定日期更早的数据等) –