我有一个数据库设计问题,我一直在研究,但无法得到正确的答案。假设我们有两个表house_schema
和house
,如下所示:
house_schema {
id big int,
house_height int,
house_width int,
house_decoration vchar(1024),
build_date timestamp,
primary key id,
}
house {
id big int,
owner vchar(255),
price big int,
house_schema_id big int,
primary key id,
foreign key fk_house_house_schema_id (`house_schema_id`) reference `house_schema`.`id`
}
house_schema
表存储house
的一些物理属性。在软件UI上,用户选择一个模式,然后单击“构建”按钮。房屋建成并存储在house
中。还有一些其他表格如house_schema
来描述如何建造房屋。
在简单的设计中,外键看起来效果很好。但是,当构建器决定删除他们认为已过时的架构时,它会引发问题。已经有一些从架构构建的房屋,外键阻止它被删除。如果我们将外键更改为DELETE ON CASCADE
,那么这些房屋将丢失它所构建的信息。
处理此问题的最佳设计模式是什么?我能想象的是拥有一个house_schema
的重复表,一旦建立了一个房子,就将house_schema
中的行复制到重复的表中。
但是,这会导致数据库中出现大量重复的表,因为我有多个类似的表house_schema
。它似乎违反了数据库规范化规则。
有人有个好主意吗?
答案 0 :(得分:3)
如果您想保留用于构建房屋的模式的历史记录,典型的解决方案是在house_schema
表上实施软删除。
而不是实际删除house_schema
中的行,你必须
Active
列false
请注意,有一些关于软删除的材料,包括建议反对和。
根据个人经验,我们在主应用程序中对可选项目(下拉列表)采用软删除,目前尚无任何问题。
当一个项目过时时,它的值必须保留在任何使用它的位置,但是对于新文档,它不应该再出现在de下拉列表中。我还必须遇到一个更好的解决方案,能够处理这种情况其他而不是软删除。
答案 1 :(得分:0)
有一些可能性:
您可以在house_schema中有一个“已删除”字段,您可以标记该字段以指示架构不再存在。这意味着要更改许多查询。
您可以拥有一个“不可删除”的默认架构,当一个架构被删除时,它的房屋将会回归。
答案 2 :(得分:0)
作为一个简单的解决方案,您可以向house_schema添加“已删除”标记。这样你就可以保留历史条目。向用户显示可用的house_schema条目时,过滤掉未删除的内容。
答案 3 :(得分:0)
可能添加了“deprecated_schema”,您只需将要删除的house_schema行复制到已弃用的保留部分。您需要一个字段来存储原始的house_schema ID字段,这样您仍然可以访问房子表中的正确条目。
然后你可以从house_schema表中删除,并且仍然可以根据该模式保留对房屋的访问权。
答案 4 :(得分:0)
只是为了增加另一种观点,您是否考虑过* house_schema *中存储的详细信息实际上可能是 house 的属性,应该存储为这样?
这可以看作过度规范化的情况。