“钻石形关系”的正式术语是什么?

cha*_*eda 3 erd database-design terminology

考虑以下“菱形”实体关系图:

菱形ER图

我试图找到一些关于为什么这是一个糟糕的设计的正式读物 - 但谷歌搜索“菱形表关系”只会出现 ERD 符号。

这种关系叫什么?为什么它是一个糟糕的表设计(如果是)?

Mic*_*een 5

您必须添加鱼尾纹(或您喜欢的任何符号)才能让我们正确理解图表。我选择将其解释为自上而下的定向。

    top table
     |     |
     ^     ^
   Left   Right
      |    |
      ^    ^
      Bottom

Fig: Diamond pattern
Run Code Online (Sandbox Code Playgroud)

我不记得曾经看到过这种模式的明确命名。“钻石”似乎和任何一样好。

因此,我不相信这是一个循环引用。为此,您必须能够跟随“许多”回到原点:

    top table
     |     |
     ^     ^
   Left   Right
      |    |
      ^    ^
      Bottom

Fig: Diamond pattern
Run Code Online (Sandbox Code Playgroud)

我质疑菱形图案是糟糕设计的前提。对于某些应用,它可能是完全合适的。也许它只是不适合你。

作为一个玩具示例,考虑一个小型多租户应用程序来跟踪热办公。我们有实体类型 Company、Employee、Desk 和 DeskAllocation。一家公司雇佣了很多员工。公司提供许多办公桌。每个员工每天可以坐在不同的办公桌前。员工自然只能坐在雇主提供的办公桌前。

我们可以通过公司的商业登记号或我们提供的虚构号码来识别公司。没关系。我们将称之为 CompanyId。

公司为其雇员创建员工 ID。由于每家公司都有一名员工想要被雇佣 #1,因此我们必须有一个复合键 (CompanyId, EmployeeId)。

每家公司都有自己的办公桌标签方案,但大多数都使用简单的数字序列。所以 Desk 的 PK 是组合(CompanyId, DeskId)。

那么DeskAllocation的PK是什么?它将是 Employee 的 PK,Desk 的 PK 和日期列。前两个本身是复合的,每个都包含 CompanyId。这似乎是多余的,甚至是错误的,但对于执行“坐在雇主的办公桌前”规则来说是不可或缺的。这可以作为检查约束来实现。

DeskAllocation 的伪代码将是

table DeskAllocation
(
  DeskCompanyId,
  DeskId,
  EmployeeCompanyId,
  EmployeeId,
  AllocationDate

  primary key
  (
    DeskCompanyId,
    DeskId,
    EmployeeCompanyId,
    EmployeeId,
    AllocationDate
  )

  foreign key FK_Desk
  (DeskCompanyId, DeskId) references Desk(CompanyId, DeskId),

  foreign key FK_Employee
  (EmployeeCompanyId, EmployeeId) references Employee(CompanyId, EmployeeId)

  constraint CHECK DeskCompanyId = EmployeeCompanyId
)
Run Code Online (Sandbox Code Playgroud)

这似乎是人为的,但我已经在汽车定价应用程序中实现了这种模式。