You could do 1. but as your attributes are not fixed, they are just name value pairs this seems like a lot of duplication.
2 seems like a bad idea, as it is awkward to enforce the integrity with this sort of set up.
for 3, could you have a link table in the middle for an attribute group, which contains the id of the group and the ids of the individual GenericAttribute
s, then you have the AttributeGroupId
as a property of the person and of the pet?
Table AttributeGroup
- Id (PK)
- GenericAttributeId (PK,FK)
Table GenericAttribute
- Id (PK)
- Name
- Value
Person
- Id (PK)
- Name
- AttributeGroupId
Pet
- Id (PK)
- Name
- AttributeGroupId
so then the AttributeGroupId
identifies a collection of GenericAttribute
instances which are associated with the Pet
or the Person
. This also means that if you need to attribute something else in the future you just need to add the AttributeGroupId
to that thing.
EDIT:
You really need to consider why you are doing this though. Are your attributes really dynamic, as this is the only reason I can think of that you would want this model? ie are your users defining the attributes in the application, can they add any attribute they want to a Person or a Pet? If not, if the application is in control of the attributes then you should consider Brock's advice. If the users are entering the attributes and their values themselves then you may need a model like this but it makes your queries much more complicated. If you can avoid it then its probably right to do so. I gave this as an example of a solution to your question, I can't suggest that it is a good idea without knowing more about your specific use case.
EDIT2:
As you have a fixed set of attributes that both a Pet and a Person can have you could have:
Attributes
- Id (PK)
- Attribute1
- Attribute2
...
- AttributeN
Person
- Id (PK)
- Name
- AttributesId (FK)
Pet
- Id (PK)
- Name
- AttributesId (FK)
Which avoids the duplication in all of the attributes if they are numerous and allows fairly simple querying, integrity checking, and strong typing of the data.