请批评我提出的数据库设计

时间:2011-08-08 15:13:04

标签: sql sql-server database-design

我希望得到一些关于我提议的数据库架构的反馈。这是业务场景。我们需要维护一个由一些匿名ID识别的几百万个家庭的清单。我们还需要维护一份描述这些家庭的人口统计数据和其他属性的列表。通过从外部数据文件追加新属性,属性列表将随着时间的推移而增长。例如,想象一下营销人员会买一个狗爱好者的名单,并要求将其作为一个名为“喜欢狗”的新属性加载。

这是我提出的架构。我有家庭和相关属性的单独表格。在家庭表中,有一个标识列和一个散列标识符,它们将来自我们的数据提供者。散列值是出于隐私原因。我们不允许知道家庭是谁(例如我们没有姓名,地址等)。每个属性还有属性列,以二进制方式指示家庭是否具有该属性。我已经分离到另一个表中的属性的实际定义。

HOUSEHOLD TABLE
ID | External ID | Attribute 1 | Attribute 2 | Attribute N
0  | hash val    |      1      |      0      |    0
1  | hash val    |      1      |      0      |    1
2  | hash val    |      0      |      0      |    0
3  | hash val    |      1      |      0      |    0
4  | hash val    |      0      |      1      |    1 
5  | hash val    |      1      |      0      |    0
N  | hash val    |      1      |      0      |    0



HOUSEHOLD ATTRIBUTE TABLE
AttributeID  | Attribute Name | Attribute Description
0            |       Rich     |  Has income over $x
1            |       SUV      |  Drives SUV
2            |       XBox     |  Owns an XBox
N            |       Urban    |  Lives in urban area

当我们加载新属性和/或家庭时,我们可能会收到指示家庭的哈希值的平面文件以及属性的二进制值。我预计,属性的名称和描述将在元数据文档中。

这就是我现在必须要做的所有背景。我很欣赏那些在性能方面批评我提出的架构的答案(我们将从web gui对数据库运行很多计数)和可维护性(例如,加载新数据和更新现有数据的简易性) 。我提出的架构是如何解决问题的?为什么/为什么不呢?如果您采用不同的方式,您的设计会是什么样的?

假设我们不需要在这些表上维护版本控制(尽管这可能是未来的要求)。

编辑:为了使这个开放得少一点,我想重新解释这个问题如下。我的数据库设计是否符合我概述的给定业务场景的最佳实践?如果没有,我应该改变什么?

4 个答案:

答案 0 :(得分:4)

更好的设计是

Household TABLE (HouseholdID, External ID)
Attribute TABLE (HouseholdID, AttributeID)
lkp_Attribute TABLE (AttributeID, Attribute Name, Attribute Description)

这样,每次添加新属性时都不必更改Household表。

答案 1 :(得分:4)

家庭TABLE是从维护的角度相当差,则必须更新表模式到每次添加一种新的家庭ATTRIBUTE时间添加新的列,并还持有大量的冗余信息。

我会添加另一个将家庭与属性相关联的表格:

HOUSEHOLD_ATTRIBUTE_RELATIONSHIP 
HouseholdID  | AttributeID 
0            |       0     
3            |       2
etc ... 

此表中的每一行表示特定家庭具有特定属性。这样,您可以添加新属性,而无需更新数据库架构。

此外,请确保对这些表之间的关系使用外键约束。

如果您开始遇到严重的性能问题,则应该开始取消规范化并添加冗余数据。

答案 2 :(得分:1)

我认为当新属性不频繁时我只会在表中添加一列,因此在您的情况下只需添加列LikesDogs。这让事情变得简单。

另一种方法是将数据进一步规范化,因此您可以添加如下行来代替添加列:

Create table houseHoldData as (
  HouseHold_Id int, -- points to household row
  Attribute_Id int, -- this points to a row in your attribute table
  Value double 
)

然后您可以使用PIVOT运算符将其转换为更易读的格式。但我认为只添加列将是最简单的方法。如果它不要过度;不需要。

GJ

答案 3 :(得分:1)

对于它的价值(正如JNK所说,这可能因为没有“正确”答案而被关闭),我真的不鼓励为每个属性分别设置一个列。如果您决定稍后添加一些属性怎么办?如果你想删除一些怎么办?你重命名列吗?

最好(在我看来)将您的可用属性保存在单独的House / Attribute行表中,使用外键指向House和Attribute表。

所以在你的情况下你有

HouseID | AttributeID
---------------------
0         1
1         1
1         2...N