2010-06-02 63 views
2

假设我有以下表和关系:数据建模帮助 - 添加其他表格,更改现有表格的用法或其他内容?

Person 
- Id (PK) 
- Name 

一个人可以有0个或更多的宠物:

Pet 
- Id (PK) 
- PersonId (FK) 
- Name 

一个人可以有0个或多个属性(如年龄,身高,体重) :

PersonAttribute 
_ Id (PK) 
- PersonId (FK) 
- Name 
- Value 

问题:我也需要表示宠物属性。事实证明,这些宠物属性在大多数情况下与人的属性相同(例如,宠物也可以具有年龄,身高和体重)。我如何表示宠物属性?

  1. 我是否创建PetAttribute表?

    PetAttribute

    • ID(PK)
    • PetId(FK)
    • 名称
    • 价值
  2. 修改我PersonAttribute到GenericAttribute并在其2个外键 - 一个连接到人,另一个连接到宠物?

    GenericAttribute

    • ID(PK)
    • PERSONID(FK)
    • PetId(FK)
    • 名称
    • 价值

    注意:如果PERSONID设置,那么PetId没有设置。如果设置了PetId,PersonId没有设置。

  3. 做点别的?

回答

3

实际上,您应该删除PersonAttribute表,并将Person(年龄,身高,体重等)列添加到Person表中。

将相似的列添加到Pet表中。这避免了称为“实体属性值表”的常见初学者错误。例如,请参阅“Five Simple Database Design Errors You Should Avoid”。

只有当所有者可以拥有多个确切属性时,才能将“属性”(如重量)放在单独的表中。然后,表格应该是特定的,“WeightHistory”,如果它是一段时间内的权重列表等。

+0

这是很好的建议。你需要考虑为什么你需要以通用的方式存储属性。他们真的是动态的吗?用你应该考虑的事情更新我的答案。 – 2010-06-02 08:54:55

+0

@BrockAdams:但是,如果一个人的属性从记录到记录有什么不同呢?例如,对于某个人来说,我们存储的是重量,但并非全部。这会导致记录中有很多空列。这不就是数据库设计不好的标志吗? – StackOverflowNewbie 2010-06-02 09:14:03

+0

@StackOverflowNewbie,不一定。如果属性是固定的,但可能是空的,那就这样吧。当你真正需要支持的是某些列中的空值时,这是比支持动态属性(带有所有问题)更好的解决方案。你有多少物业,更重要的是它们是固定的?这应该是什么决定你的设计恕我直言。 – 2010-06-02 09:21:40

1

你可以做1,但因为你的属性不固定,它们只是名称值对,这似乎是很多重复。

2似乎是一个坏主意,因为用这种设置强制执行完整性很尴尬。

for 3,您是否可以在属性组的中间有一个链接表,其中包含组的id和个人GenericAttribute s的ID,然后您将AttributeGroupId作为该人的属性,宠物?

Table AttributeGroup 
- Id (PK) 
- GenericAttributeId (PK,FK) 

Table GenericAttribute 
- Id (PK) 
- Name 
- Value 

Person 
- Id (PK) 
- Name 
- AttributeGroupId 

Pet 
- Id (PK) 
- Name 
- AttributeGroupId 

所以则AttributeGroupId识别GenericAttribute其与PetPerson相关实例的集合。这也意味着,如果你需要在将来为别的东西添加属性,你只需要添加AttributeGroupId即可。

编辑:

你真的需要考虑你为什么这样做,虽然。你的属性是否真的是动态的,因为这是我能想到你会想要这个模型的唯一原因?即你的用户是否在应用程序中定义属性,他们是否可以将他们想要的任何属性添加到Person或Pet?如果没有,如果应用程序在控制属性,那么你应该考虑布洛克的建议。如果用户自己输入了属性及其值,那么您可能需要这样的模型,但这会让您的查询变得更加复杂。如果你能避免它,那么它可能是正确的。我把这个作为解决你的问题的一个例子,我不能说在不了解你的具体用例的情况下这是一个好主意。

EDIT2:

当你有一个固定的属性集合中既有宠物和一个人可以有,你可以有:

Attributes 
- Id (PK) 
- Attribute1 
- Attribute2 
... 
- AttributeN 

Person 
- Id (PK) 
- Name 
- AttributesId (FK) 

Pet 
- Id (PK) 
- Name 
- AttributesId (FK) 

,如果它们是避免所有属性的重复众多,并允许相当简单的查询,完整性检查和强大的数据输入。

0

我认为,当你模拟PetAttribute和PersonAttribute更深时,你会发现它们是更通用的特性的特化也许称为PersonOrPetAttribute。

如果取决于我,我只是简单地将两个表分开,直到没有PersonOrPetAttribute表开始增加查询难度。

如果你看到它不同,那么你应该做一个谷歌搜索“泛化专业化关系建模”。这将为您找到几篇关于使用表建模gen-spec模式的好文章。这些文章会告诉你更多关于如何做到这一点的事情,而不是我将要做出的回应。

相关问题