I have a table of people quite standard stuff e.g. :
CREATE TABLE [Contact](
[ContactID] [bigint] IDENTITY(1,1) NOT NULL,
[ContactType] [nvarchar](50) NULL,
[Forename] [nvarchar](60) NULL,
[Surname] [nvarchar](60) NULL,
[Company] [nvarchar](60) NULL
}
Example Data :
01, "Student", "Bob", "Smith", Blank
02, "Staff", "Robert", "Smithe", "Roberts And Sons"
Etc
This table contains all the fields common to all contacts. However i have some “types” of contact that may or may not have a field which is specic only to that type of contact. For example if the record has “ContactType=’student'” i want to store an extra field called “studentid”. There are many different types of contact each with slightly different field requirements. To add to this situation at somepoint in the future each contact type might have extra fields added.
If i add each field to the contacts table i would end up with lots of fields which are not required for 99% of the records. So i was planning on creating a second table like this:
CREATE TABLE [ContactMetaData](
[ContactID] [bigint] NOT NULL,
[PropName] [nvarchar](200) NOT NULL,
[PropData] [nvarchar](200) NULL
)
Example Data:
01, "StudentID", "0123456"
01, "CourseName", "IT"
01, "Average", "10"
02, "Ranking", "22"
02, "ProductTypes", "IT Equipment"
ETC
For each extra field i just add a record into this table with the name and value for the field. I can use code to pull this information up etc.
My question is
Is this the best approach as i’m stumped of another way other than a huge table with every single field. Given this approach is it possible to do complex querys across many of the property fields and if so how? e.g. how would i list all the students on the “IT” course with an “Average” of 10 whos “forename” starts with “D”?
Yes, if you really have many many fields that are not used, go for this approach (called an EAV data structure). You can do all queries on this structure that you can with a normal model, just use appropriate joins to pivot them.