当前位置: 首页 > 面试题库 >

保持参照完整性-好还是坏?

司易安
2023-03-14
问题内容

我们计划使用触发器和需要审计的每个表的单独历史表在数据库中引入简单的审计跟踪。

例如考虑表StudentScore,它只有很少的外键(例如StudentID,CourseID)将其链接到相应的父表(Student&Course)。

Table StudentScore (
    StudentScoreID, -- PK
    StudentID ref Student(StudentID),  -- FK to Student
    CourseID ref Course(CourseID),   -- FK to Course
)

如果StudentScore需要审核,我们计划创建审核表StudentScoreHistory-

Table StudentScoreHistory (
    StudentScoreHistoryID, -- PK
    StudentScoreID,
    StudentID,
    CourseID,
    AuditActionCode,
    AuditDateTime,
    AuditActionUserID
)

如果修改了StudentScore中的任何行,我们会将旧行移至StudentScoreHistory。

在设计讨论中提出的观点之一是,将StudentHistory表中的StudentID和CourseID设置为FK,以保持参照完整性。支持这一点的理由是,我们
通常总是 进行软(逻辑布尔标志)删除而不是硬删除,这有利于保持引用完整性,以确保我们在审计表中没有任何孤立的ID。

Table StudentScoreHistory (
    StudentScoreHistoryID, -- PK
    StudentScoreID,
    StudentID ref Student(StudentID), -- FK to Student
    CourseID ref Course(CourseID), -- FK to Course
    AuditActionCode,
    AuditDateTime,
    AuditActionUserID
)

对我来说,这似乎有些奇怪。我确实同意@Jonathan
Leffler的评论
,即审核记录不应阻止删除父数据。相反,如果需要,则应通过主表中的外键而不是审计表中的外键进行处理。我想征求您的意见,以确保在将外键扩展到审计表时不会丢失任何价值。

现在我的问题是: 在历史记录表中包含这些外键是否是一个好的设计?

我们将不胜感激有关关键论点的任何细节(例如性能,最佳实践,设计灵活性等)。

为了任何寻求特定目的和我们环境的人的利益:

目的:

  1. 维护关键数据历史
  2. 允许审核用户活动并支持重新创建方案
  3. 在一定程度上允许回滚用户活动

环境:

  • 交易数据库
  • 并非每个表都需要审核
  • 尽可能使用软删除,特别是用于静态/参考数据
  • 很少有高度事务性的表使用硬删除

问题答案:

在讨论审计时,我将回到其背后的目的。它实际上不是备份,而是历史记录。例如,对于StudentScore,您可能要确保不要丢失一个事实,即学生原来有65%的学生现在有95%的事实。通过该审核跟踪,您可以回顾所做的更改,以了解发生了什么以及由谁执行。由此,您可以确定特定用户为滥用系统所做的事情。在某些方面,这可能是一种备份,因为您可以将这些更改回滚到以前的状态,而无需回滚整个表。

考虑到这一点(如果我对您将其用于什么的假设是正确的),则您唯一希望建立FK /
PK关系的位置是历史记录表及其“实时”对应项之间。您的审核(历史)表不应引用任何其他表,因为它不再是该系统的一部分。相反,它只是一张表中发生的事情的记录。时期。您可能要考虑的唯一参照完整性是在历史表和实时表之间(因此可能的FK
/ PK关系)。如果允许从活动表中删除记录,则不要在历史记录表中包括FK。然后,历史记录表可能包含已删除的记录(如果允许删除,这就是您想要的记录)。

使用此历史记录表,不要混淆主数据库中的关系完整性。历史记录表都是独立的。它们仅用作一个表(而不是一组表)的历史记录。

可以将两个历史记录表关联在一起,甚至可以将实时表和历史记录表之间的关系更高级(例如,具有实时和历史记录的学生和课程),因此您甚至可以处理删除学生的可能性(颤抖)因为记录仍将位于历史记录表中。唯一的问题是,如果您不保留特定表的历史记录,那么在这种情况下,您将选择丢失该数据(如果允许删除)。



 类似资料:
  • 问题内容: 我正在尝试解析Web请求并将其保存到数据库。我有3个模型,第一个节点是virtualDocument。这是uniq表(根据请求url)。VirtualRequest表具有所有erquest主体,而HttpHeaderList表根据其virtualRequest bean ID具有所有thhp标头。 当我尝试保存第一个日志时,出现了这样的错误; 这是VirtualDocument bea

  • 我有和表,我在laravel中建立了一对一的关系,这很好,但如果我尝试在不引用任何用户(id)的情况下手动将数据(外键用户id)添加到电话表中,它也会起作用。 在mysql(phpmyadmin)中,迁移后没有建立外键关系。 所以我想问,外键的优势是什么,如果它不把任何约束放在数据库表中,或者如果有任何方法可以使用laravel添加这些约束,请告诉我。 代码片段 app/Phone.php app

  • 问题内容: 在多个数据库之间保持引用完整性的最佳实践是什么?因为没有内置功能 还是对单个数据库进行分区更好? 更新 请参见下面的kevin的示例。那是我的情况。我的库存数据库具有引用雇员数据库中的employeeId的表。 这些数据库当前维护在不同的位置(不同的服务器) 问题答案: 使用2k05 / 2k08,最好对单个数据库进行分区。您拥有将数据存储在多个数据库中的所有好处,同时能够使用单个数据

  • 本文向大家介绍详解sql中的参照完整性(一对一,一对多,多对多),包括了详解sql中的参照完整性(一对一,一对多,多对多)的使用技巧和注意事项,需要的朋友参考一下 一、参照完整性 参照完整性指的就是多表之间的设计,主要使用外键约束。 多表设计: 一对多、多对多、一对一设计 1.一对多 关联主要语句: constraint cus_ord_fk foreign key (customer_id) R

  • 1.1.1.完整性 Android是一个完整的平台,即为移动设备提供的一套完整的软件架构。 面向开发者,Android提供了一套完整的工具和框架,以简化开发过程、提高开发效率。想要开发Android应用的话,Android SDK就是你所需的一切——甚至不需要一台真正的手机。 面向用户,Android开机即用。而且,用户可以按照自己的喜好做出相当程度的自定义。 面向生产厂商,Android就是令他

  • 直译更好还是意译更好?这也是困扰许多译者的一大问题。不但资深译者时常为此犯难,就是初学者,尚未动笔便发愁直译更好还是意译更好,因此步履维艰的,也到有人在。所以,说清楚直译和意译的问题大有必要。 什么是直译?直译即word-for-word translation,也称作literal translation,意思是“按原有的形式来翻译”。典型的例子是将“I have a pair of shoes