Sql 递归关系的数据库设计

Sql 递归关系的数据库设计,sql,database,database-design,data-modeling,erd,Sql,Database,Database Design,Data Modeling,Erd,考虑以下情况,我试图为一家公司的数据库建模: 实体:员工,经理,部门 一个员工只在一个部门工作,而部门可能有许多员工在其中工作 一个经理只能管理一个部门,同样的部门也只能有一个经理 一名经理监督许多员工,但一名员工只由一名经理监督 现在我有两种建模方法: 第一个解决方案: 我会考虑管理器< /C>实体继承自雇员>代码>实体,考虑到我将保留对管理者来说唯一的数据(例如,奖金和状态)。< /P> 既然部门和员工之间的关系是1:N,那么我将把 部门Id作为工作 关系 既然部门和经理之间的关系

考虑以下情况,我试图为一家公司的数据库建模:

  • 实体:
    员工
    经理
    部门
  • 一个
    员工
    只在一个
    部门
    工作,而
    部门
    可能有许多
    员工
    在其中工作
  • 一个
    经理
    只能管理一个
    部门
    ,同样的
    部门
    也只能有一个
    经理
  • 一名
    经理
    监督许多
    员工
    ,但一名
    员工
    只由一名
    经理
    监督
现在我有两种建模方法:

第一个解决方案:

我会考虑<代码>管理器< /C>实体继承自<代码>雇员>代码>实体,考虑到我将保留对管理者来说唯一的数据(例如,奖金和状态)。< /P>

  • 既然
    部门
    员工
    之间的关系是
    1:N
    ,那么我将把
    部门Id
    作为
    工作
    关系

  • 既然
    部门
    经理
    之间的关系是
    1:1
    ,那么我将把
    部门Id
    作为
    管理者的
    表中的外键
    关系

问题:如何表示
经理
员工
之间的递归关系?


第二种解决方案:

我会考虑不使用<代码>管理器> /代码>实体,因为其他<代码>雇员< /代码>也可能有<代码>奖金<代码>和<代码>状态< /代码>。(实际上,我添加了这两个属性只是为了看看如何在这两种情况下对其建模)

  • 既然
    部门
    员工
    之间的关系是
    1:N
    ,那么我将把
    部门Id
    作为
    工作
    关系
  • 由于
    Employee
    Manager
    之间的关系是
    1:N
    ,因此我将
    Employee Id
    作为
    Employee
    表中的外键,用于管理
    
    关系,并将其称为
    Manager Id
问题:如何表示
经理
部门
之间的关系?


问题:

  • 这两种设计都有明显的错误吗
  • 如何解决这两种情况下的每个问题
  • 有比这两个更好的解决方案吗
  • 我的意见是:

    表Person,您将在其中添加员工和经理的信息,经理也是人,您知道吗?:),您有一个managerId字段链接到经理的Id

    表department包含部门信息


    而且,如果员工可以属于多个部门,则创建一个表employee\u department来关联他们。如果一名员工只能属于一个部门,而您不需要关系中的更多信息,请在员工表中添加departmentID字段。

    我认为这是最好的解决方案:

    经理是管理一个部门的雇员。 可通过下一个流获得的递归关系:

    员工有一个部门 一个部门有一名员工作为经理


    为employee表提供一个EmployeeType列来定义角色可能很方便。

    我可能会使用以下内容:

    该模型具有以下特点:

    • 经理“继承”员工。
      • 若要表示员工,请在“员工”中插入一行
      • 若要表示经理,请在EMPLOYEE中插入一行,并在manager中插入一行
    • 一个部门可以有多个员工
    • 每个部门正好有一名经理,每个经理管理0或1个部门
    • 主管可以是普通员工,也可以是经理
    • 部门无需“匹配”:
      • 主管可以在与受监管员工不同的部门工作
      • 经理可以从他工作的地方管理不同的部门
      • 如果主管是经理,那么他管理的部门、他工作的部门以及他/她的受监管员工的部门都可以不同
    注意:如果您的DBMS不支持延迟约束,您将希望使DEPARTMENT.MANAGER_ID为NULL,以打破可能阻止您插入新数据的循环


    如果需要匹配部门,那么您可以使用DBMS特定的技术(例如触发器或“特殊”约束),或者将部门ID“传播”到员工的PK中。这种传播最终实现了匹配:

    由于EMPLOYEE_ID必须是全局唯一的,因此它不能与DEPARTMENT_ID一起保留在复合密钥中。因此,我们将其设为备用密钥,并在PK中使用代理EMPLOYEE_NO

    这种模式可以防止管理一个部门并在另一个部门工作的经理,或管理不同部门员工的主管


    如果您不熟悉该符号


    …它表示一个“类别”。在这种情况下,您可以简单地将其解释为员工和经理之间的“1对0或1”关系。

    不必详细说明,我向您保证,从长远来看,员工/经理/部门解决方案是不愉快的来源(起初),然后是真正的PITA(以后)适用于负责维护数据库和/或开发其界面的人员。所以我建议你坚持你的第二个建议

    关于经理/部门关系,您有mai
    Manager id (PK, surrogate)
    Department id (FK)
    Employee id (FK)
    beginningDate
    endingDate
    
    Position id (PK, surrogate)
    Department id (FK)
    Employee id (FK)
    Position Level (FK)
    beginningDate
    endingDate
    
    Tbl_Employee.id_EmployeeManager
    
    Tbl_Department.id_DepartmentManager
    
    Tbl_Department.id_DepartmentManager -> Tbl_Employee.id_EmployeeManager
    
    Tbl_Department.id_DepartmentManager -> Tbl_Employee.id_Employee