【问题标题】:Database tables: One-to-many of different types数据库表:不同类型的一对多
【发布时间】:2012-03-28 12:14:48
【问题描述】:

由于我在工作中的保密性,我对这种情况进行了类比。请尝试关注问题,而不是“为什么不重命名此表、合并这些表等”。因为实际问题要复杂得多。

这是交易,

假设我有一个“员工加薪”记录需要批准。

有一个包含单个“用户”的表。

有一些表格将用户分组在一起,例如,“经理”、“高管”、“工资单”、“财务”。这些分组是具有不同属性的不同类型。

在创建“加薪”记录时,创建记录的用户还同时选择其中一些组(经理、高管等)和/或可以“批准”加薪的单个用户。

将单个“EmployeePayRise”记录与 0 个或多个用户记录以及每个分组中的 0 个或多个相关联的最佳方法是什么。

【问题讨论】:

    标签: database database-design relational-database


    【解决方案1】:

    我会假设用户链接到组?如果是这样,在这种情况下,我只需将employeePayRise 记录链接到它适用的一个用户和可以批准的用户。所以基本上你会有两列代表这个。 EmployeePayRise.employeeId 和 EmployeePayRise.approvalById 列。如果您需要进入群组,您将加入 EmployeePayRise.employeeId = Employee.id 记录。保持简单,而不会使您的设计过于复杂。

    【讨论】:

    【解决方案2】:

    我的第一个想法是创建一个表格,将各个审批者与加薪行关联起来。

    create table pay_rise_approvers (
      pay_rise_id integer not null references some_other_pay_rise_table (pay_rise_id),
      pay_rise_approver_id integer not null references users (user_id),
      primary key (pay_rise_id, pay_rise_approver_id)
    );
    

    您不能有好的外键有时引用经理,而有时引用工资单。用户似乎是外键的逻辑目标。

    如果创建加薪行(未显示)的人选择经理,则用户界面负责将每位经理插入该表中的一行。这部分很简单。

    出现在多个组中的人可能是个问题。我可以想象一位副总裁同时出现在“执行”和“财务”组中。我不认为这特别难处理,但它确实需要一些远见。假设输入数据的人改变了主意,决定从表中删除所有高管。是否应该罢免同时从事财务工作的高管?

    另一个问题是很有可能不是每个用户都应该被允许批准加薪。在实施任何解决方案之前,我会考虑一下。

    【讨论】:

    【解决方案3】:

    我知道它看起来很难看,但我认为解决方案可能是在表中包含 table_name 和联合查询

    create table approve_pay_rise (
      rise_proposal varchar2(10)     -- foreign key to payrise table
    , approver varchar2(10)          -- key of record in table named in other_table
    , other_table varchar2(15) );
    
    insert into approve_pay_rise values ('prop000001', 'e0009999', 'USERS');
    insert into approve_pay_rise values ('prop000001', 'm0002200', 'MANAGERS');
    

    然后在代码中使用 case 语句,为每个 other_table 值重复语句(select ... where other_table = '' .. select ... where other_table = '')或联合选择。

    我不得不承认,当我遇到它时我会发抖,现在我会在输入建议后去洗手,但它确实有效。

    【讨论】:

    【解决方案4】:

    听起来您可能需要两个表(“ApprovalUsers”和“ApprovalGroups”)。 SELECT 语句将是来自“ApprovalUsers”的 UserId 和来自与 PayRiseId 相关的“ApprovalGroups”的任何其他用户组的 UserID 的 UNION。

    SELECT UserID
    INTO   #TempApprovers
    FROM   ApprovalUsers 
    WHERE  PayRiseId = 12345
    
    IF EXISTS (SELECT GroupName FROM ApprovalGroups WHERE GroupName = "Executives" and PayRiseId = 12345)
    BEGIN
        SELECT UserID
        INTO   #TempApprovers
        FROM   Executives
    END
    
    .... 
    

    编辑:这将/可能重复用户 ID,因此您可能希望按用户 ID 分组(即从 #TempApprovers GROUP BY 用户 ID 中选择用户 ID)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-18
      • 2017-01-30
      • 2012-12-04
      • 2016-07-02
      • 1970-01-01
      • 2013-03-12
      相关资源
      最近更新 更多