【问题标题】:Unnecessary Redundancy with Tables表不必要的冗余
【发布时间】:2010-03-21 08:25:20
【问题描述】:

我的物品如下:当然这只是一个总结。但是我正在使用为“详细信息”表显示的一种方法来表示一种“继承”,可以这么说 - 因为“项目”和“可下载”将是相同的,除了每个都有一些额外的相关字段只对他们。

我的问题在于这种设计模式。这种事情在我们的项目中出现了很多很多次——有没有更聪明的方法来处理它?我基本上需要尽可能地规范化表格。我对数据库非常陌生,所以这对我来说非常困惑。

有 5 个项目。奖励、物品、购买、代币和下载。它们都非常非常相似,除了每个都有一些仅与自身相关的数据。我尝试将声明字段(如枚举器“类型”字段)与可为空的列结合使用,但有人告诉我这是一种不好的方法。我所做的是将所有类似的东西放在一个表中,然后每种类型都有自己的表,该表引用“基本”表中的列。

问题出现在关系或联结上。将所有这些链接回客户。每种类型都需要大约 2 个额外的表来正确地将所有数据连接在一起——因此,我的数据库变得非常非常大。这种行为有更明智的做法吗?

Item
ID      | GUID
Name      | varchar(64)

Product
ID      | GUID
Name      | varchar(64)
Store     | GUID [ FK ]
Details  | GUID [FK]

Downloadable
ID      | GUID
Name      | varchar(64)
Url    | nvarchar(2048)
Details | GUID [FK]

Details
ID           | GUID
Price         | decimal
Description | text

Peripherals [ JUNCTION ]
ID      | GUID
Detail      | GUID [FK]

Store

ID      | GUID
Addresses   | GUID

Addresses
ID      | GUID
Name        | nvarchar(64)
State    | int [FK]
ZipCode | int
Address | nvarchar(64)


State
ID      | int
Name        | varchar(32)

【问题讨论】:

    标签: database-design


    【解决方案1】:

    这种继承对于关系数据库来说总是有点小技巧。您所拥有的是一种方法,它是解决问题的最传统方法。你最终会做很多交叉表,但这可能很好。

    另一种方法是采用一些非规范化并将表折叠成一个表。包括一个表示项目类型的类型字段,然后将所有字段的并集放在该表中。所以你会有一张像

    这样的桌子
    ID  | GUID
    Type | GUID [FK]
    Name        | nvarchar(64)
    State    | int [FK]
    ZipCode | int
    Address | nvarchar(64)
    Name      | varchar(64)
    Url    | nvarchar(2048)
    Store     | GUID [ FK ]
    Details  | GUID [FK]
    ...
    

    这意味着您的表格中有一堆空字段。

    您还可以采取更加分散的方法并构建您的表格,例如

    Item:
    ID | GUID
    
    ItemPropertyType:
    ID | GUID
    Name | nvarchar(50)
    
    ItemProperty:
    ID | GUID
    ItemID | GUID [FK]
    ItemPropertyTypeID | GUID
    charValue | varchar(64)
    

    每个项目属性引用一个项目。要构建一个项目,您只需收集它拥有的 ItemProperties。如果您想查找 Name 为“bill”的所有项目,那么您可以这样做

    select ItemID from ItemProperties ip, ItemPropertyTypes ipn where ipn.ID = ip.ItemPropertyTypeID and ipt.Name='Name' and ip.charValue='bill'
    

    Jeff 实际上写了一些关于这个话题的博客 http://www.codinghorror.com/blog/2008/07/maybe-normalizing-isnt-normal.html

    【讨论】:

    • 您的第一种方法将业务意义与一行联系起来(类型#3 =“下载”)。这通常不是一个好的做法,因为模型不能完全反映设计。您的第二种方法是基于元数据的,如果需要,这很好,但它往往在系统中有大量数据时表现不佳,并且需要一些数据维护(孤立行等)。这种方法也称为实体-属性-值或 EAV。
    • 抱歉,读到后面的内容听起来比我想象的更说教和迂腐。 :)
    猜你喜欢
    • 2017-12-19
    • 2021-02-26
    • 2023-04-03
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    相关资源
    最近更新 更多