Database design 不必要的表格冗余

Database design 不必要的表格冗余,database-design,Database Design,我的项目如下:;这只是一个总结。但是我使用了一个为“Detail”表显示的方法来表示一种类型的“继承”,可以这么说,因为“Item”和“Downloadable”将是相同的,只是每个都有一些仅与它们相关的附加字段 我的问题是这个设计模式。这类事情在我们的项目中多次出现——有没有更智能的方法来处理它?我基本上需要尽可能规范化这些表。我对数据库非常陌生,所以这对我来说非常混乱 共有5项。奖励、物品、购买、代币和下载。它们都非常非常相似,只是每个都有一些只与自身相关的数据。我曾尝试将声明字段(如枚举器

我的项目如下:;这只是一个总结。但是我使用了一个为“Detail”表显示的方法来表示一种类型的“继承”,可以这么说,因为“Item”和“Downloadable”将是相同的,只是每个都有一些仅与它们相关的附加字段

我的问题是这个设计模式。这类事情在我们的项目中多次出现——有没有更智能的方法来处理它?我基本上需要尽可能规范化这些表。我对数据库非常陌生,所以这对我来说非常混乱

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

问题发生在关系或连接上。将所有这些链接回客户。每种类型都需要大约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)

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

另一种方法是采用一些非规范化并将表折叠成一个表。包括一个表示项目类型的类型字段,然后将所有字段合并到该表中。那么你想要一张像这样的桌子

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。如果您想找到所有名为“bill”的项目,那么您可以这样做

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

Jeff实际上在博客上写了一点关于这个主题的文章

您的第一种方法将业务意义与行联系起来(键入#3=“下载”)。这通常不是一个好的做法,因为模型不能完全反映设计。第二种方法是基于元数据的,如果需要的话,这是可以的,但是它在处理系统中的大量数据时往往表现不佳,并且需要一些数据维护(孤立行等)。这种方法也被称为实体属性值(Entity Attribute Value)或EAV。对不起,回过头来读这篇文章听起来比我预想的更说教、更迂腐。:)