只是想知道这个设计是否有任何问题,或者它是否曾破坏数据库规范化中的任何规则。
主表有一列映射到两个(甚至更多)不同的表,因此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 | .....
......
答案 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。