【问题标题】:Normalizing a Table 6规范化表 6
【发布时间】:2012-10-03 17:37:38
【问题描述】:

我正在整理一个需要规范化的数据库,但我遇到了一个我真的不知道如何处理的问题。

我整理了一个简化的问题示例来说明它:

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

(我为尴尬的桌子道歉;新用户不允许粘贴图片)

在上表中,我有一个属性(金额),它在功能上依赖于项目 ID(我认为),但并非每个项目 ID 都存在(因为继承的项目没有货币成本)。我对数据库比较陌生,但我在任何初学者教程或文献中都找不到与此类似的问题。任何帮助将不胜感激。

【问题讨论】:

    标签: database database-design normalization database-normalization


    【解决方案1】:

    为什么需要对其进行规范化?

    我可以看到一些数据完整性挑战,但没有明显的结构问题。

    “采购”与是否存在价值/货币之间的隐含依赖关系很棘手,但与密钥无关,因此实际上没什么大不了的。

    如果我们要成为纯粹主义者(例如,这是出于家庭作业的目的),那么我们将处理两种类型的物品,继承物品和购买物品。由于它们不是同一类型的事物,因此应将它们建模为两个独立的实体,即 InheritedItem 和 BoughtItem,仅包含它们需要的列。

    为了获得所有项目的组合视图(例如,获得总重量),您可以使用视图或 UNION sql 查询。

    如果我们正在寻找数据库中的对象模型,那么我们可以分解出常见的超类型(Item),并使用外键对超类型表的子类型(InheritedItem,BoughtItem)进行建模(下面的ypercube解释非常好),但与仅对子类型建模相比,这非常复杂,而且对未来的影响更小。

    最后一点是很多争论的主题,但实际上,根据我的经验,在数据库中对具体的超类型进行建模比将它们抽象化会导致更多的痛苦。好的,这可能超出了您的预期:)。

    【讨论】:

      【解决方案2】:

      不仅Amount,一切都依赖于ItemID,因为这似乎是一个候选键。

      Procurement'inherited' (或@XIVsolutions 和你所指出的0 成本)时,您的依赖是CurrencyAmountNULL(我猜这意味着未知/无效)提及“继承的物品没有金钱成本”

      换句话说,iems 分为两种(采购),两种类型之一的项目不具有所有属性。

      这可以通过超类型/子类型拆分来解决。您有一个超类型表 (Item) 和两个子类型表(ItemBoughtItemInherited),其中每个表都与超类型表具有 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 专业化”上搜索。

      【讨论】:

      • 在这种特殊情况下,以我的思维方式,继承项目的成本只是零,而不是零。
      • @XIVSolutions:我认为这对标准化并不重要。这是一个常数值(我同意 0 是合理的,是的),在整个 ItemInherited 表中保持不变。
      • 我的印象是,从初学者的角度来看,OP 正在努力解决的问题之一是他表中的某些项目的成本值为零。我试图从本质上澄清你所说的,那个问题不是正常化问题。
      • 我认为将继承项目提取到他们自己的表中没有任何价值。它们仍然是一个项目,与 OP 提出的模式中的任何其他项目具有所有相同的属性。一旦消除了 Null 值问题,它们就是同一个东西,属于同一张表。
      • @XIVSolutions:你将如何处理部分依赖? (Precurement='inherited' -> 成本=0)
      【解决方案3】:

      我将创建两个新表 ItemProcurementCurrencies

      如果我没记错的话,根据提供的数据,金额是项目本身采购的一部分(当项目没有被继承时),因此我会将Amount 和@987654325 分组@新实体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 | 
      +------------+---------+-----------------+
      

      【讨论】:

      • 这允许您以不同的成本和不同的货币类型采购多个相同的项目类型。我错过了,但是。
      【解决方案4】:

      这是我的即兴建议:

      更新:质量将是浮点数/十进制/双精度数,具体取决于您的数据库,成本将是处理金钱的最佳类型(在 SQL Server 2008 中,它是“金钱”,但这些东西会有所不同)。

      另一个更新:继承项目的成本应该为零,而不是零(事实上,有时会有间接成本,以税收的形式,但我离题了......)。因此,您的项目表应该需要一个成本值,即使该成本为零。它不应该为空。

      如果您有任何问题,请告诉我。 . .

      【讨论】:

      • 哎呀。 “Item”表中的“ProcurementMethodID”拼写错误。抱歉......
      猜你喜欢
      • 1970-01-01
      • 2011-05-09
      • 2012-12-31
      • 1970-01-01
      • 2018-02-13
      • 2011-03-31
      • 1970-01-01
      相关资源
      最近更新 更多