使用外键的风险引用同一个表的主键

时间:2018-02-08 16:27:45

标签: sql asp.net-mvc

我继承了一个项目,该项目有一个名为Users的表,它为每个有权使用应用程序的用户存储唯一的ID。该表格为User_ID。此表还有一个名为Mgr_User_ID的列,用于跟踪个人报告的对象。我想将User_ID作为列Mgr_user_ID的外键,以便我可以在我使用此表的MVC项目中轻松访问管理器信息。

我的问题基本上是,这被认为是不好的做法,是否存在与此类事情相关的风险?

2 个答案:

答案 0 :(得分:3)

自引用表是一种非常常见的做法。这就是你如何为任何等级关系建模。

最大的“风险”,实际上不是风险,如果你试图走遍整个层次结构(例如你想创建一个组织结构图),你需要编写一个递归方法(可以如果你不习惯它,有时会成为一个大脑扭转者。)

此外,事先决定如何识别层次结构的顶部(即不向任何人报告的经理)。在某些系统中,Mgr_User_ID设置为null,而在其他系统中,它们决定使其与User_ID相同。我已经使用了这两种方法,并且实际上没有一种方法优于另一方,只要确保在数据中工作的每个人都理解规则,如果你有任何其他类似的关系,那么对所有这些方法使用相同的方法

答案 1 :(得分:0)

这通常被称为"自我加入"的表格。员工表或组织表通常很常见。只要表格的行(工人 - >经理,外地办事处 - >总部)中存在层次结构,就可以使用自联接。

这不是一个坏习惯。实际上,将employee表分成worker表和manager表会更糟糕。因为这会通过在两个表中管理基本相同的对象而使事情变得复杂。

但是,使用自联接查询表可能不直观,并且会产生冗长的代码。但是,您可以通过使用视图来简化操作。如果您有一个具有Mgr_User_ID的员工表。也许你可以编写这样的查询并使其成为一个视图。如果您只想在一个表中找到工作人员的姓名和经理姓名:

CREATE VIEW dbo.DIMUser
AS 
SELECT Users.UserId
, Users.UserName
, MUsers.UserId AS ManagerId
, MUsers.UserName AS ManagerName
FROM dbo.Users AS Users
    LEFT JOIN dbo.Users AS MUsers
    ON Users.Mgr_User_ID = MUsers.Id