我正在整理一个我需要规范化的数据库,而且我遇到了一个我真不知道如何处理的问题。
我已经将我的问题的简化示例放在一起来说明它:
Item ID___Mass___Procurement__Currency__________Amount
0__________2kg___inherited____null________________null
1_________13kg___bought_______US dollars_________47.20
2__________5kg___bought_______British Pounds______3.10
3_________11kg___inherited____null________________null
4__________9kg___bought_______US dollars__________1.32
(我为尴尬的表道歉;新用户不允许粘贴图片)
在上表中,我有一个属性(Amount),它在功能上依赖于Item ID(我认为),但是对于每个Item ID都不存在(因为继承的项目没有货币成本)。我对数据库比较陌生,但在任何初学者教程或文献中都找不到类似的问题。任何帮助将不胜感激。
答案 0 :(得分:2)
我只想创建两个新表ItemProcurement
和Currencies
。
如果我没有错,根据提供的数据,金额是项目本身采购的一部分(当项目未被继承时),因此我会将Amount
和新实体CurrencyID
中的ItemProcurement
个字段。
如您所见,继承的项目在ItemProcurement
表中没有条目。
关于主Item
表,如果您希望采购类型只有两个不同的值,那么我会使用char(1)
列(不同于B
=> bougth, I
=>继承)。
我看起来像这样:
数据将如下所示:
TABLE Items
+-------+-------+--------------------+
| ID | Mass | ProcurementMethod |
|-------+-------+--------------------+
| 0 | 2 | I |
+-------+-------+--------------------+
| 1 | 13 | B |
+-------+-------+--------------------+
| 2 | 5 | B |
+-------+-------+--------------------+
TABLE ItemProcurement
+--------+-------------+------------+
| ItemID | CurrencyID | Amount |
|--------+-------------+------------+
| 1 | 840 | 47.20 |
+--------+-------------+------------+
| 2 | 826 | 3.10 |
+--------+-------------+------------+
TABLE Currencies
+------------+---------+-----------------+
| CurrencyID | ISOCode | Description |
|------------+---------+-----------------+
| 840 | USD | US dollars |
+------------+---------+-----------------+
| 826 | GBP | British Pounds |
+------------+---------+-----------------+
答案 1 :(得分:1)
这是我的袖手旁观的建议:
更新:质量将是一个Float / Decimal / Double,具体取决于您的Db,成本将是处理资金的最佳类型(在SQL Server 2008中,它是“Money”但这些事情各不相同)。
另一个更新:继承项目的成本应为零,而不是空(事实上,有时候是间接成本,以税收的形式,但我离题......)。因此,即使成本为零,您的项目表也应该需要成本值。它不应该为空。
如果您有疑问,请告诉我。 。
答案 2 :(得分:1)
不仅Amount
,一切都依赖于ItemID
,因为这似乎是一个候选键。
当Currency
为Amount
时,NULL
和Procurement
为'inherited'
(我猜这意味着未知/无效) @XIVsolutions指出的0成本,并且当你提到“继承的项目没有金钱成本”)
换句话说,iems分为两种类型(采购),两种类型之一的项目没有所有属性。
这可以通过超类型/子类型拆分来解决。您有一个超类型表(Item
)和两个子类型表(ItemBought
和ItemInherited
),其中每个表与超类型表都有1::0..1
关系。所有项目共有的属性将在超类型表中,并且尊重子类型表中的所有其他属性:
Item
----------------------------
ItemID Mass Procurement
0 2kg inherited
1 13kg bought
2 5kg bought
3 11kg inherited
4 9kg bought
ItemBought
---------------------------------
ItemID Currency Amount
1 US dollars 47.20
2 British Pounds 3.10
4 US dollars 1.32
ItemInherited
-------------
ItemID
0
3
ItemInherited
表。有关此模式的其他问题,请查找标记:Class-Table-Inheritance。在您使用它的同时,也可以查找Shared-Primary-Key。要获得更加孜孜不倦的待遇,请关注“ER专业化”。
答案 3 :(得分:1)
为什么需要将其标准化?
我可以看到一些数据完整性挑战,但没有明显的结构问题。
“采购”与价值/货币的存在与否之间的隐含依赖性是棘手的,但与密钥无关,因此实际上并不是什么大问题。
如果我们要成为纯粹主义者(例如这是出于家庭作业目的),那么我们正在处理两种类型的项目,继承项目和购买项目。由于它们不是同一类型的东西,它们应该被建模为两个独立的实体,即InheritedItem和BoughtItem,只有它们需要的列。
为了获得所有项目的组合视图(例如,获得总权重),您将使用视图或UNION SQL查询。
如果我们在数据库中查找对象模型,那么我们可以将常见的超类型(Item)分解出来,并使用外键将子类型(InheritedItem,BoughtItem)建模到超类型表(下面的ypercube说明非常好) ),但这比仅仅模拟子类型更复杂,更不具有前瞻性。
最后一点是很多争论的主题,但实际上,根据我的经验,在数据库中建模具体的超类型会导致更多的痛苦,而不是将它们抽象化。好吧,这可能超出你想要的范围:)。