Reputation:
My application involves testing and there are three different kinds of tests: Exam, Objective and Custom. Here are the three schemas (with some columns missing in each for this simplified example)
CREATE TABLE [dbo].[Exam] (
[ExamId] INT IDENTITY (1, 1) NOT NULL,
[SubjectId] INT NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
...
);
CREATE TABLE [dbo].[Objective] (
[ObjectiveId] INT IDENTITY (1, 1) NOT NULL,
[SubjectId] INT NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
...
)
CREATE TABLE [dbo].[Custom] (
[CustomId] INT IDENTITY (1, 1) NOT NULL,
[SubjectId] INT NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
...
)
Any of these can have records in the Test table:
CREATE TABLE [dbo].[Test] (
[TestId] INT IDENTITY (1, 1) NOT NULL,
[ExamId] INT NOT NULL,
[Title] NVARCHAR (100) NULL,
[Status] INT NOT NULL
);
But how do I map this? The test table above just has an ExamId as originally Exam was my only source. Now I have three sources then how can I also link the other two entities Objective and Custom to the Test table?
Upvotes: 0
Views: 78
Reputation: 36
How about this test table ?
CREATE TABLE [dbo].[Test] (
[TestId] INT IDENTITY (1, 1) NOT NULL,
[ExamId] INT NULL,
[ObjectiveId] INT NULL,
[CustomId] INT NULL,
[Title] NVARCHAR (100) NULL,
[Status] INT NOT NULL
FOREIGN KEY (ExamId) REFERENCES [dbo].[Exam](ExamId)
FOREIGN KEY (ObjectiveId) REFERENCES [dbo].[Objective](ObjectiveId)
FOREIGN KEY (CustomId) REFERENCES [dbo].[Custom](CustomId)
);
Upvotes: 2
Reputation: 94939
So a test was always an exam so far, but now it can be either Exam, Objective or Custom.
One solution would be to make ExamID nullable in your test table and add two more nullable ids ObjectiveID and CustomID.
You would always use just one of the IDs per test record. To avoid errors you'd write a check constraint:
ALTER TABLE dbo.Test ADD CONSTRAINT CK_Test_Type CHECK
(
(ExamId IS NOT NULL AND ObjectiveID IS NULL AND CustomID IS NULL)
OR
(ExamId IS NULL AND ObjectiveID IS NOT NULL AND CustomID IS NULL)
OR
(ExamId IS NULL AND ObjectiveID IS NULL AND CustomID IS NOT NULL)
);
The other option would be not to have three tables Exam, Objective and Custom, but only one TestDetail with a column for the type (Exam, Objective or Custom).
Which of the two options is more appropriate depends on how different the three tables are.
Upvotes: 0