Question

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?

Was it helpful?

Solution

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)
);

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top