【问题标题】:Normalization of database for timesheet tool and ensure data integrity时间表工具的数据库规范化并确保数据完整性
【发布时间】:2011-01-22 07:18:06
【问题描述】:

我正在创建一个时间表应用程序。我有以下实体(其中包括):

  • 公司
  • 员工 = 与公司关联的员工
  • 客户 = 与公司相关的客户

到目前为止,我有以下(缩写)数据库设置:

Company
 - id  
 - name

Employee
 - id  
 - companyId (FK to Company.id)  
 - name

Client
 - id  
 - companyId (FK to Company.id)  
 - name

现在,我希望员工与客户相关联,但该客户与员工工作的公司相关联。您将如何保证数据库级别的数据完整性?还是我应该仅仅依靠应用程序来保证数据的完整性?

我想过像这样创建一个多对多表:

EmployeeClient  
 - employeeId (FK to Employee.id)  
 - companyId  \  (combined FK to Client.companyId, Client.id)
 - clientId   /  

因此,当我为员工插入客户以及员工的公司 ID 时,如果客户端与员工的公司 ID 没有关联,数据库应该会阻止这种情况。这有意义吗?因为这仍然不能保证员工与公司有关联。你如何处理这些事情?

更新
场景如下:

  • 一家公司有多名员工。员工只会与一家公司相关联。

  • 一家公司也有多个客户。客户只会与一家公司相关联。

    (可以说,公司是一个沙盒)。

  • 公司的员工可以与其公司的客户相关联,但前提是该客户是公司客户的一部分。

换句话说:
该应用程序将允许公司创建/添加员工和创建/添加客户(因此在 Employee 和 Client 表中的 companyId FK)。接下来,公司将被允许将某些客户分配给它的某些员工(EmployeeClient 表)。

想象一个员工在为几个客户编写可计费时间的项目,但不得允许该员工为非雇主(公司)分配的客户编写可计费时间。因此,员工不会自动访问公司的所有客户,而只能访问公司为他们选择的客户。希望这对此事有更多的了解。

【问题讨论】:

    标签: mysql normalization data-integrity


    【解决方案1】:

    如果您想从数据库级别执行此操作,那么我会将逻辑放在存储过程中。然后,如果适用,存储的过程代码将关联这两者,但这意味着(假设您将外键放在客户表中的员工)一个客户只与一名员工相关联。这是你想要的吗?

    还要注意,您表中的员工通过其公司关联与所有此类客户间接关联。如果所有员工都自动与他们公司的所有新客户相关联,那么您可能只想编写一个查询来检查这一点。

    【讨论】:

    • 您好 Hannes,感谢您的回复。 “(假设您将员工的外键放在客户表中)”。我假设您提到了 EmployeeClient 表(m 到 n)?如果是这样,那么是的,员工将与他们公司的客户单独联系。因此,对于您的第二个观察:员工不会自动与公司客户联系起来,这就是我需要这个工作的原因。我希望一些员工在 m 到 n 表中与他们工作的公司的一些客户相关联。那么,在这种情况下,SP 似乎是唯一可行的选择,对吧?
    • 我实际上的意思是在您的 Client 表中有一个employeeId,但是如果您想要多对多关系,那么可以使用关联的 EmployeeClient 表并有一个名为 associateClientWithEmployee 的存储过程来为您执行逻辑。跨度>
    • 我刚刚再次阅读了您问题的最后一段:“因此,当我为员工插入客户以及员工的公司 ID 时,当客户未关联时,数据库应防止这种情况发生带有员工的公司 ID”。我现在更多的是在同一页面上:为此,我会将检查逻辑放入触发器中。如果检查失败,则抛出异常。顺便问一下,这是什么数据库?
    • 再次感谢汉内斯。 RDBMS 是带有 InnoDB 表的 MySql。你认为这可以通过 MySQL 中的触发器来实现吗?我不太熟悉触发器来告诉你真相(顺便说一下,SP 也不是),但如果你认为它对 MySql 是可行的,我可以毫无问题地研究它。这听起来是个不错的选择,也许比 SP 更好。
    • 不幸的是,Mysql 还不支持触发器的“引发错误”概念。有一些技巧可以实现这一点,这里解释了其中一个:brokenbuild.com/blog/2006/08/15/…。不过,看起来 Philip Kelley 的最新更新可能会为您提供答案。
    【解决方案2】:

    (这不是一个答案,但它并不适合作为问题评论。)

    为您的设计问题提供的数据引出了许多问题:

    • 员工是否与公司客户相关联?或者...
    • 员工是否只与客户相关联,并且(因此)公司与该客户相关联?
    • 如果员工和客户与公司相关联,那么员工是否因此与该公司的所有员工相关联,还是必须选择?

    更新

    就数据建模而言,您似乎只需将 EmployeeClient 中的外键扩展为 Employee,如下所示:

    EmployeeClient
     - companyId
     - employeeId
     - clientId
    

    所有三列的复合主键。

    (companyId, clientId) 上的外键进入 Client
    将 (companyId, employeeId) 上的外键插入 Employee

    因此,EmployeeClient 中定义的所有关系都要求 Client 和 Employee 共享相同的 clientId。

    【讨论】:

    • 您好菲利普,感谢您的回复。请参阅我更新的问题以获得进一步的解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 2015-02-15
    • 1970-01-01
    • 2015-06-10
    • 2014-02-08
    • 1970-01-01
    相关资源
    最近更新 更多