一列映射到不同表中的多列

时间:2015-06-10 16:04:25

标签: sql database oracle database-design

只是想知道这个设计是否有任何问题,或者它是否曾破坏数据库规范化中的任何规则。

主表有一列映射到两个(甚至更多)不同的表,因此reference列中的数据可能会与多个表中的主键混合。

创建不同的关联表(主要 - > A和主要 - > B)是更好的设计吗?

表专业

item id | reference
-----------------------
 id 1  |  a1 pk from tb A
 id 2  |  b1 pk from tb B
 id 3  |  a2 pk from tb A
 id 4  |  b2 pk from tb B
 id 5  |  a3 pk from tb A
 id 6  |  a4 pk from tb A
 id 7  |  b3 pk from tb B
 id 8  |  b4 pk from tb B
 ......

表A

sub item id | 
-----------------------
 id a1  |  .....
 id a2  |  .....
 id a3  |  .....
 id a4  |  .....
 ......

表B

sub item id | 
-----------------------
 id b1  |  .....
 id b2  |  .....
 id b3  |  .....
 id b4  |  .....
 ......

4 个答案:

答案 0 :(得分:1)

您的表格严重违反了Boyce-Codd Normal Form (3NF+),因为您不知道您的密钥引用了哪个表格。这是一个语义差异,每列应该完全描述一件事(在这种情况下,上下文不同,因为每个键都转到不同的表)。

因为你有表A& B作为“子项目”,你想要表A和A表。 B引用表Major的主键作为其父级,具体取决于其中的其他内容。 您的父/子关系已经倒置:父级(专业)不必引用其子表(A& B),该子级引用父级PK,理想情况下由外键强制执行。然后您可以从子项中选择并加入以从父项中获取所有相关记录,而不从另一个子项中选择不相关的记录并且必须在其中过滤掉它们。你的where子句。

所以,他们可能看起来如下:

表专业:

item id | [more columns]
-----------------------
 1  |  [foo]
 2  |  [bar]
....

表A:

sub item id | MajorID (FK to Table Major) | [other columns]
-----------------------
id 1  | 1 (PK from Table Major) | .....
....

表B:

sub item id | MajorID (FK to Table Major) | [other columns]
-----------------------
id 1  | 2 (PK from Table Major) | .....
....

然后您可以使用此查询选择所有B,而不必担心A:

SELECT *
FROM  [Table B] as b INNER JOIN
  [Table Major] as maj ON b.MajorID = maj.ID

表A与表B的区别是什么?如果它们具有相同的内容,您可能只需要添加一列以将它们彼此区分为子类型/子项目?

答案 1 :(得分:0)

只要你将你引用的表的数量保持在最低限度并不是一个想法太糟糕,在Table Major中你会想要添加一个额外的字段来识别它属于哪个表。

这取决于Table Major对您的项目的重要性。如果它位于宇宙的中心,我会说也许(更倾向于否),如果没有,那么你可能会没事。

ORM执行您的建议,但在实施之前我会先查看其他选项。

答案 2 :(得分:0)

我不知道你想做什么。在我看来,没有必要这样做。如果你想在其他2个表之间建立关系,你可以创建一个表,其中包含定义该关系的那些表的键,你可以通过添加两个标识关系中表的其他字段来进行概括。 但是所描述的表格(主要 - 每列混合键)可以通过简单的union获得。

答案 3 :(得分:0)

我定义了单独的字段来引用表A和B,如:

TABLE MAJOR
  ID    | REFERENCE_A | REFERENCE_B
  id 1  | a1          | NULL
  id 2  | NULL        | b1
  id 3  | a2          | NULL
  id 4  | NULL        | b2
  id 5  | a3          | NULL
  id 6  | a4          | NULL
  id 7  | NULL        | b3 pk from tb B
  id 8  | NULL        | b4 pk from tb B

通过这种方式,您可以更轻松地了解每个字段所指的内容,并且可以在表MAJOR和其他表之间定义外键关系,以帮助确保数据的一致性。如果需要,它还允许MAJOR引用A a B - 如果不需要,可以使用简单的CHECK约束来确保最多一个(REFERENCE_A,REFERENCE_B)不是NULL。