【问题标题】:Database Design: Circular reference and how to correct it数据库设计:循环参考以及如何更正它
【发布时间】:2020-03-21 02:05:16
【问题描述】:

这是循环引用吗?如果是这样,我该如何改进我的模型?

【问题讨论】:

  • 我认为您的某些基数可能是错误的。从“fk”标签来看,Employee 和 Item 都引用了 Client;项目还引用了员工。我认为这没有任何根本性的问题,但您的基数似乎与“fk”标签相矛盾。
  • 谢谢@nvogel。我已经更正了基数。
  • 我觉得不错。我没有看到其他需要纠正的地方。没有循环依赖,因为客户端不依赖其他任何东西
  • 表项上的“itemID (int, fk) 不应该是“EmployeeID”吗?

标签: mysql sql-server postgresql database-design circular-reference


【解决方案1】:

您没有任何循环引用。我将数据模型解释为:

An Item belongs to exactly 1 Client
An Item belongs to 0 or 1 Employee
An Employee belongs to exactly 1 Client

循环引用会添加An Employees to exactly 1 Item

在 cmets 中,您说项目始终与其员工属于同一个客户,但并非所有项目都属于员工。

有几种方法可以对此进行建模。

我要避免的是将 ClientID 作为 Item 上的非空外键关系 - 这重复了“没有显式客户端 ID 的项目从其员工继承客户端 ID”的逻辑。它没有表现力(阅读架构的人无法弄清楚),并且会带来错误。

一种选择是使item->employeeitem-> client 的基数都是可选的(即0..1)。然后,您的约定将是 if an item has a client relationship, it may not have an employee relationshipif an item has an employee relationship, it may not have an explicit client relationship; the client is determined by the employee. 您无法在架构中清晰地表达这一点,并且必须将其构建到您的数据访问代码中。

另一种选择是创建两种类型的项目,一种具有 clientID 外部关系,另一种具有 employeeId 外部关系。从模式的角度来看,这更具表现力——大概有一些业务概念可以用来命名表。但是,如果Item 有很多属性,那么您就重复了很多。

最后,您可以将项目与客户或员工的关系存储在单独的连接表中:

Item
-------
ItemID
...

ItemEmployees
-----------------
ItemID
EmployeeID

ItemClients
----------
ItemID
ClientID

这避免了 Item 上的属性重复,但表达力较差,因为它使用了更常用于多对多关系的模式,并且没有明确声明“非此即彼”。

【讨论】:

  • 谢谢@NevilleKuyt。项目始终与其员工属于同一个客户,但项目可能属于客户而不属于员工。在那种情况下,我怎样才能删除“条件”重复?
  • 如果一个项目可能并不总是属于某个员工,那么您的基数就会出现错误 - 我认为它应该是 0..1。您能否更新问题,我会在答案中回复?
猜你喜欢
  • 2018-07-11
  • 2011-07-20
  • 2014-08-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2019-01-09
  • 2014-02-12
  • 1970-01-01
相关资源
最近更新 更多