I have a small database I designed and I am experiencing some difficulties. I'm hoping some generous readers might give me some advice. Design environment is Access 97 but that's mostly irrelevant... I might run this on, say, an MSSQL backend some day.
The easiest way to explain this might be to give examples. Here is some imaginary data in my current format:
[tt]Entities
ID FullName Type Parent
1 MyCompany 1 1
2 TheRed, Erik 2 1
3 ZZ Svcs 3 3
4 OftenWrong, Bob 2 3
5 Affiliate Co. 1 1
EntityTypes
ID Name CanBeParent TableSource
1 Company True Companies
2 User False Users
3 Partner True Partners
Users
ID Entity FirstName LastName Password
1 2 Erik TheRed *****
2 4 Bob OftenWrong *****
Partners
ID Entity Name Rating
1 3 ZZ Svcs 1450[/tt]
There is also a Vendors table I left out.
My design considerations:
1) I need to be able to assign a project to either a user or a partner, and conceivably to a vendor as well. So, I put these different types of things into an Entities table together. Additionally, I must know which users belong to which parent entity. Some entity types can be parents, others cannot.
2) Different kinds of entities have different information. A user has a first name, a last name, and a password, while a vendor does not. I do not want to store this information in the Entities table, it belongs in a separate table for each unique entity type. If I did, there would be many blank fields not to mention the difficulty of creating a form that handled each type properly.
3) I want to be able to create new Entity types or add fields for each Entity at will, with the minimum of work to forms and tables to accomodate. My Entity management form already uses the TableSource field to dynamically switch to the correct subform, so adding a new Entity type would mean creating one new subform and all my existing code would work. I have been careful in my queries so that new entity types will handled intelligently (for example, using fields like CanBeParent, or deciding whether to use inclusion or exclusion logic: "WHERE EntityType=2" vs. "WHERE EntityType Not In (1,3,4)").
While I solved many problems with this approach, I also generated some:
Do I store an entities name in the Entities table or in the table specific to that entity? I chose the non-normalized approach of storing a non-editable FullName in the Entities table and letting the type-specific tables organize the information according to its own needs. Users have a first name and last name, partners do not. Any edits to a user must trigger an update in the Entities table to maintain data integrity.
Maybe this approach was wrong... maybe I should eliminate the name from the Entities table to not store the same information twice. But then, how do I display a list of all Entities with their names using a simple query?
- I could do inner joins for each type and union the results together. This is messy and if I ever add a new Entity type I will have to modify the queries.
- I could do left joins and have the name be a calculated field concatenating the names together, nulls would be converted to empty strings. Same problem as previous.
- I don't think the contents of a record can be used to specify a join table. If so, I could use my TableSource field for this purpose.
- I can't think of another way.
I have seen some web references to this sort of One-To-Zero-Or-Many relationship, but no detail about practical usage considerations.
Would anyone care to comment on what I've mentioned already, or make suggestions or observations about things I haven't even considered yet?
I have used this Entities layout in the past and I expect to use it again in the future and I would really appreciate some help in working out the details!
Thank you,
E²
The easiest way to explain this might be to give examples. Here is some imaginary data in my current format:
[tt]Entities
ID FullName Type Parent
1 MyCompany 1 1
2 TheRed, Erik 2 1
3 ZZ Svcs 3 3
4 OftenWrong, Bob 2 3
5 Affiliate Co. 1 1
EntityTypes
ID Name CanBeParent TableSource
1 Company True Companies
2 User False Users
3 Partner True Partners
Users
ID Entity FirstName LastName Password
1 2 Erik TheRed *****
2 4 Bob OftenWrong *****
Partners
ID Entity Name Rating
1 3 ZZ Svcs 1450[/tt]
There is also a Vendors table I left out.
My design considerations:
1) I need to be able to assign a project to either a user or a partner, and conceivably to a vendor as well. So, I put these different types of things into an Entities table together. Additionally, I must know which users belong to which parent entity. Some entity types can be parents, others cannot.
2) Different kinds of entities have different information. A user has a first name, a last name, and a password, while a vendor does not. I do not want to store this information in the Entities table, it belongs in a separate table for each unique entity type. If I did, there would be many blank fields not to mention the difficulty of creating a form that handled each type properly.
3) I want to be able to create new Entity types or add fields for each Entity at will, with the minimum of work to forms and tables to accomodate. My Entity management form already uses the TableSource field to dynamically switch to the correct subform, so adding a new Entity type would mean creating one new subform and all my existing code would work. I have been careful in my queries so that new entity types will handled intelligently (for example, using fields like CanBeParent, or deciding whether to use inclusion or exclusion logic: "WHERE EntityType=2" vs. "WHERE EntityType Not In (1,3,4)").
While I solved many problems with this approach, I also generated some:
Do I store an entities name in the Entities table or in the table specific to that entity? I chose the non-normalized approach of storing a non-editable FullName in the Entities table and letting the type-specific tables organize the information according to its own needs. Users have a first name and last name, partners do not. Any edits to a user must trigger an update in the Entities table to maintain data integrity.
Maybe this approach was wrong... maybe I should eliminate the name from the Entities table to not store the same information twice. But then, how do I display a list of all Entities with their names using a simple query?
- I could do inner joins for each type and union the results together. This is messy and if I ever add a new Entity type I will have to modify the queries.
- I could do left joins and have the name be a calculated field concatenating the names together, nulls would be converted to empty strings. Same problem as previous.
- I don't think the contents of a record can be used to specify a join table. If so, I could use my TableSource field for this purpose.
- I can't think of another way.
I have seen some web references to this sort of One-To-Zero-Or-Many relationship, but no detail about practical usage considerations.
Would anyone care to comment on what I've mentioned already, or make suggestions or observations about things I haven't even considered yet?
I have used this Entities layout in the past and I expect to use it again in the future and I would really appreciate some help in working out the details!
Thank you,
E²