0

起初,这个问题似乎微不足道,但是...

  • 假设您的应用程序将关系数据库作为持久层进行管理。
  • 假设(例如)应用程序管理学生、课程、教师、成绩、房间。
  • 所有这些实体类型都以某种方式相互关联。

问题是,如何从持久层中删除实体,但保持关系完整性和逻辑一致性。

更具体地说:关于隐私的常规要求可能会迫使您从系统中删除参加过课程 B 的学生 A - 在 B 完成后。观察:

  • 如果要删除学生 A,则也需要删除所有关系,以保持持久层的完整性。不幸的是,参加该课程的学生人数也减少了一位。事实上,我们希望 B 的服务员人数保持不变。
  • 如果有人通过将名字和名字设置为@anonymous@ 来匿名学生 A,UNIQE(first name, name) 条件就会被破坏(有点人为,但你明白了)。

因此,我正在寻找理论上/实际上正确的解决方案来删除实体并将逻辑信息保留在数据库中。

注意:有相当大的应用程序从不删除记录。据我所知,SAP 就是这些应用程序之一。

4

1 回答 1

1

一种方法是简单地用 NULL 覆盖隐私敏感字段,而不实际删除该行。如果敏感字段需要唯一,请将其置于可空的 UNIQUE 约束中,而是使用代理键作为外键的目标。根据定义,代理键中的数据没有意义,因此不敏感,因此不需要被 NULL 化,因此现有链接仍然存在。

在您的示例中,大多数学生的字段将被 NULL 化,但他/她仍将保持与课程的链接。


或者,有一个特殊的“匿名”行,并在删除“真实”行时重新链接到它。根据链接所需的语义,这可能合理,也可能不合理。

在您的示例中,当实际学生被删除时,课程将重新链接到特殊的匿名学生。这样,一门课程仍然保留了适当数量的学生,但您现在必须实现将同一课程多次链接到同一(匿名)学生的能力,因为同一课程的多个真实学生可能会被删除。


另一种选择是“特殊”逐案处理,例如通过存储单独的计数器或其他“元信息”。

在您的示例中,如果学生人数(每门课程)即使在学生被删除后也很重要 - 只需有一个包含学生人数的字段(在课程表中)。一旦您开始删除学生,此字段将不再匹配实际学生的数量,但会保留过去的出勤人数。您必须仔细更新此计数以保持数据一致性 - 使用触发器和可能的锁定可能是最好的选择。此外,您必须弄清楚如果学生从课程中辍学会发生什么 - 辍学之前或之后的数字是正确的数字吗?

于 2013-08-30T00:48:46.357 回答