4

我有一个数据库设计问题,我已经研究了一段时间,但无法得到正确的答案。假设我们有两个表,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。它似乎违反了数据库规范化规则。

有人有好主意吗?

4

5 回答 5

3

如果您想保留用于建造房屋的模式的历史记录,典型的解决方案是在您的表上实施软删除。house_schema

而不是实际删除中的行,house_schema您将不得不

  • 向表中添加一Active
  • 将此列设置false为架构过时时
  • 调整您的应用程序以不显示非活动模式的

请注意,有很多关于软删除的材料,包括反对和支持。

根据个人经验,我们在主应用程序中对可选项目(下拉列表)使用软删除,到目前为止没有任何可提及的问题。

当一个项目过时时,它的价值需要在任何使用它的地方保留,但对于新文档,它不应该再出现在下拉列表中。除了软删除之外我还必须找到更好的解决方案才能处理这种情况。

于 2012-07-01T20:45:48.450 回答
0

有一些可能性:

  • 您可以在 house_schema 中有一个“已删除”字段,您可以标记该字段以指示模式不再存在。这将意味着更改许多查询。

  • 你可以有一个“不可删除”的默认模式,当一个被删除时,它的房屋将退回到该模式。

于 2012-07-01T20:47:08.573 回答
0

作为一个简单的解决方案,您可以向 house_schema 添加一个“已删除”标志。这样你就可以保留历史条目。当向用户显示可用的 house_schema 条目时,过滤为未删除。

于 2012-07-01T20:53:02.947 回答
0

可能添加了“deprecated_schema”,您只需将要删除的 house_schema 行复制到已弃用的持有部分。您需要一个字段来存储原始 house_schema ID 字段,以便您仍然可以访问 house 表中的正确条目。

然后,您可以从 house_schema 表中删除,并且仍然保留基于该模式对房屋的访问权。

于 2012-07-01T21:29:44.170 回答
0

再补充一个观点,你有没有考虑过存储在 *house_schema* 中的细节实际上是房子的属性,应该这样存储?
这可以看作是过度标准化的情况。

于 2012-07-02T01:52:46.103 回答