我想就数据库设计提出一些建议。具体来说,请考虑以下(假设的)情景:
在这种情况下,如果员工离开公司,我还要确保将其从Users
表中删除,以便他们无法再访问该软件。我可以使用ON DELETE CASCADE
作为EmployeeID
Employees
和Users
中UserLog
之间FK关系的一部分实现此目的。
但是,我不想从UserLog
删除他们的详细信息,因为我有兴趣整理人们花在软件上的时间以及他们不再在公司工作的事实并不意味着他们的用户行为不再相关。
我剩下的是一个表{{1}},它与我数据库中的任何其他表没有关系。 这是一个明智的想法吗?
浏览过书籍等等/ googled online我没有遇到过任何与其他人没有任何关系的数据库模式,所以我的直觉就是说我的方法不健全......
我很欣赏一些指导。
答案 0 :(得分:5)
在这种情况下,我个人的偏好是通过向Employees表添加“DeletedDate”列来“软删除”员工。这将允许您使用UserLog表保持参照完整性,并且所有员工(过去和现在)的所有详细信息在数据库中仍然可用。
这种方法的缺点是您需要添加应用程序逻辑来检查活跃的员工。
答案 1 :(得分:3)
是的,这是非常明智的。日志只是对永不改变的数据的原始审计。它不需要规范化(也不应该)和/或链接到其他表。
理想情况下,我会将写入量大的审计日志记录完全放在不同的数据库中,而不是阅读繁重的日常事务。它们可能随着时间的推移而不同但只要你了解它们之间的根本区别,从小处开始就可以将它们保存在同一个数据库中。
另外,我建议不要删除表中的用户。可能在它们上面有某种IsActive或IsDeleted位,它们会使应用程序无效,但如果可能,应该避免删除。
答案 2 :(得分:2)
您遇到的问题是,完全可以为从未存在的用户插入UserLog数据,因为没有指向定义有效用户的表的链接。
我想说也许更好的做法是将用户标记为无效,并在他们离开时删除所有他们的个人详细信息,而不是完全删除记录。
这并不是说在数据库中没有引用其他表的表(或多个表)是有效的。
答案 3 :(得分:2)
这是一个明智的想法
问题是这个。由于数据未链接,您可以从employee表中删除某些内容,并且仍然在UserLog中有引用。删除员工信息后,您无法知道日志数据与哪些关联。这个可以吗?技术上是的。没有什么可以阻止你这样做,但那你为什么要保留数据呢?您也无法保证表中的数据实际上是关于员工的。有人可能会意外地在不属于任何人的表中输入错误的EmployeeID。密钥有助于防止数据损坏。拥有额外数据总比拥有不良数据更好。
我发现你永远不想删除数据。空间很便宜,你可以添加标志等来显示记录不活跃。是的,这确实会导致更多工作(这可以通过创建仅显示活跃员工的视图来快速解决),并且说您永远不应该删除数据,但是您开始将数据链接在一起。删除变得非常困难。如果您不是为了删除记录而不添加FK,那么您需要重新考虑您的策略。
依赖级联删除也非常危险。您所说的模型是,无论何时您不希望删除数据,您都必须知道不要将FK添加到该表,并将其链接回用户。没人会忘记这一点。
答案 4 :(得分:1)
您可以通过向Users表添加bool值Deleted或Disabled来使用逻辑删除或禁用用户。
或者将UsereeId替换为UserLog中员工的姓名。
答案 5 :(得分:1)
使用软删除过程的另一种方法是在创建日志记录时存储您想要的有关用户的所有历史详细信息,而不是存储员工ID。所以你的表中可能有username,logintime,logouttime,sessionlength。
答案 6 :(得分:0)
明智?当然,因为你已经描述了你需要无限期地保留这些用户的意义。您将遇到的问题是维护表。您不必进行一次级联更新,而是必须至少使用两次更新才能插入新用户。
答案 7 :(得分:0)
我认为你建议的桌子非常好。我经常遇到与其他表没有明确关系的日志表。仅仅因为数据库是“关系型”并不意味着一切都必须与哈哈联系起来。
我注意到的一件事是您在日志中使用EmployeeID
,但不将其用作Employee
表的外键。我理解为什么你不想这样,因为你会放弃员工。但是,如果你完全放弃它们,那么EmployeeID
列就毫无意义了。
对此的解决方案是为员工(例如active
)保留一个标记,以跟踪他们是否处于活动状态。这样,日志数据就有意义了。
答案 8 :(得分:0)
IANADBA但是从数据库中删除几乎任何东西通常被认为是非常糟糕的做法。在用户表上有一些锁定的标记/“已删除”日期戳并保留你的FK会好得多。