您没有任何循环引用。我将数据模型解释为:
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->employee 和item-> client 的基数都是可选的(即0..1)。然后,您的约定将是 if an item has a client relationship, it may not have an employee relationship 和 if 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 上的属性重复,但表达力较差,因为它使用了更常用于多对多关系的模式,并且没有明确声明“非此即彼”。