假设我有以下表格:SQL:数据库的标准化,同时保持约束
____________________ ____________________
| Organisms | | Species |
|--------------------| |--------------------|
|OrganismId (int, PK)| |SpeciesId (int, PK) |
|SpeciesId (int, FK) |∞---------1|Name (varchar) |
|Name (varchar) | |____________________|
|____________________| 1
1 |
| |
| |
∞ ∞
______________________ ____________________ _______________
| OrganismPropsValues | | SpeciesProps | | Props |
|----------------------| |--------------------| |---------------|
|OrganismId (int, FK) | |PropId (int,PK,FK) | ∞-----1|PropId (int,PK)|
|PropId (int, FK) | |SpeciesId(int,PK,FK)| |Name (varchar) |
|Value (varchar) | |____________________| |_______________|
|______________________| 1
∞ |
| |
-----------------------------------------------------------
的什么,我想在这里表示一个快速的解释:假设我们有品种,如猫的清单,狗,人类等等。我们也有一套属性(缩写为Props,所以我可以更容易地将它放在图中),它们适用于一些但不一定是所有的物种 - 例如,这可能是尾巴长度(对于尾巴物种),眼睛颜色(眼睛)等。
SpeciesProps是一个链接器表,它定义了哪些属性适用于哪些物种 - 所以在这里,我们将ld具有{人类,眼睛颜色},{狗,眼睛颜色},{猫,眼睛颜色},{狗,尾巴长度},{猫,尾巴长度}。我们没有{Human,Tail Length},因为尾巴长度显然不适用于人类。
生物体表拥有物种的实际“实施” - 所以在这里我们可能有{Human,Bob},{Dog,Rufus}和{Cat,Felix}。
这里是我的问题:在OrganismPropsValues表中,我想存储每个生物体属性的'值' - 例如,我想存储Bob {眼睛颜色,蓝色}。对于Rufus,我想存储{Rufus,Eye Color,Brown}和{Rufus,Tail Length,20}(与Felix类似)。然而,我的问题是,在我详细说明的模式中,尽管SpeciesProps中不存在{Human,Tail Length}元组,但存储{Bob,Tail Length,10}是完全可能的。我怎样才能修改这个模式,这样我就可以执行在OrganismPropsValues中的SpeciesProps中定义的约束,同时保持适当的规范化?
取决于数据库(例如Oracle),我会为INSERT/UPDATE/DELETE创建一些存储过程并在其中实现任何复杂约束... – Yahia
@Yahia感谢您的建议,但是如果有方法不用介绍程序,触发器等来做到这一点。我宁愿这样做。这是MS-SQL(2008)。 – Andrew
这让我头痛。这对于查询来说是很可怕的(想想它会花费多少加入才能获得关于人类的所有数据!),这是一个糟糕的设计,我不知道从哪里开始。数据库不是对象,不应该像对象一样设计。 EAV表是一个极其糟糕的解决方案。雇用一名真正的数据库设 – HLGEM