На основі сказаного вами я використовував би таку загальну схему:
CREATE TABLE [dbo].[PollQuestion]
(
[PollQuestionId] INT NOT NULL PRIMARY KEY IDENTITY,
[QuestionText] NVARCHAR(150) NOT NULL, -- Some reasonable character limit
[Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
[Archived] DATETIME2(2) NULL, -- Remove this if you don't need to hide questions
)
CREATE TABLE [dbo].[PollOption]
(
[PollOptionId] INT NOT NULL PRIMARY KEY IDENTITY,
[PollQuestionId] INT NOT NULL, -- Link to the question here because options aren't shared across questions
[OptionText] NVARCHAR(50) NOT NULL, -- Some reasonable character limit
[Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
[Archived] DATETIME2(2) NULL -- Remove this if you don't need to hide options
CONSTRAINT [FK_PollOption_PollQuestionId_to_PollQuestion_PollQuestionId] FOREIGN KEY ([PollQuestionId]) REFERENCES [dbo].[PollQuestion]([PollQuestionId])
)
CREATE TABLE [dbo].[PollResponse]
(
[PollResponseId] INT NOT NULL PRIMARY KEY IDENTITY,
[PollOptionId] INT NOT NULL,
[UserId] INT NOT NULL,
[Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
[Archived] DATETIME2(2) NULL, -- Remove this if you don't need to hide answers
CONSTRAINT [FK_PollResponse_PollOptionId_to_PollOption_PollOptionId] FOREIGN KEY ([PollOptionId]) REFERENCES [dbo].[PollOption]([PollOptionId]),
CONSTRAINT [FK_PollResponse_UserId_to_User_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User]([UserId])
)
Вас не цікавить, чи є відповідь цифрою, датою, словом і т. Д., Оскільки дані - це відповідь на питання, а не те, з чим вам потрібно працювати безпосередньо. Крім того, дані мають значення лише в контексті питання. Оскільки такий nvarchar є найбільш універсальним читаним людиною механізмом зберігання даних.
Питання та потенційні відповіді будуть зібрані від першого користувача та вставлені в таблиці PollQuestion та PollOption. Другий користувач, який відповідає на питання, вибере зі списку відповідей (true / false = список із 2). Ви також можете розгорнути таблицю PollQuestion, щоб включити ідентифікатор користувача творця, якщо це доречно, щоб відстежувати створені ними питання.
У вашому інтерфейсі відповідь, яку вибирає користувач, може бути прив’язана до значення PollOptionId. Разом з PollQuestionId ви можете швидко переконатися, що відповідь справедлива для запитання. Їх відповідь, якщо дійсна, буде занесена в таблицю PollResponse.
Є кілька можливих проблем залежно від деталей Вашого випадку використання. Якщо перший користувач хоче використовувати математичне запитання, а ви не хочете пропонувати кілька можливих відповідей. Інша ситуація полягає в тому, що варіанти, які надає початковий користувач, є не єдиними варіантами, які може вибрати другий користувач. Ви можете переробити цю схему наступним чином, щоб підтримати ці додаткові випадки використання.
CREATE TABLE [dbo].[PollResponse]
(
[PollResponseId] INT NOT NULL PRIMARY KEY IDENTITY,
[PollOptionId] INT NULL,
[PollQuestionId] INT NOT NULL,
[UserId] INT NOT NULL,
[AlternateResponse] NVARCHAR(50) NULL, -- Some reasonable character limit
[Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
[Archived] DATETIME2(2) NULL, -- Remove this if you don't need to hide answers
CONSTRAINT [FK_PollResponse_PollOptionId_to_PollOption_PollOptionId] FOREIGN KEY ([PollOptionId]) REFERENCES [dbo].[PollOption]([PollOptionId]),
CONSTRAINT [FK_PollResponse_UserId_to_User_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[User]([UserId])
)
Я б, мабуть, також додав обмеження для перевірки, щоб переконатися, що надається варіант або альтернативна відповідь, але не обидва (варіант і альтернативна відповідь), залежно від ваших потреб.
Редагувати: спілкування типу даних для AlternateResponse.
У ідеальному світі ми могли б використовувати концепцію генерики для обробки різних типів даних для AlternateReponse. На жаль, ми не живемо в ідеальному світі. Найкращий компроміс, який я можу придумати, - це вказати, який тип даних AlternateResponse має бути в таблиці PollQuestion, і зберегти AlternateReponse в базі даних як nvarchar. Нижче наведена оновлена схема питань та нова таблиця типів даних:
CREATE TABLE [dbo].[PollQuestion]
(
[PollQuestionId] INT NOT NULL PRIMARY KEY IDENTITY,
[QuestionText] NVARCHAR(150) NOT NULL, -- Some reasonable character limit
[QuestionDataTypeId] INT NOT NULL,
[Created] DATETIME2(2) NOT NULL DEFAULT SYSUTCDATETIME(),
[Archived] DATETIME2(2) NULL, -- Remove this if you don't need to hide questions
-- Insert FK here for QuestionDataTypeId
)
CREATE TABLE [dbo].[QuestionDataType]
(
[QuestionDataTypeId] INT NOT NULL PRIMARY KEY IDENTITY,
[Description] NVARCHAR(50) NOT NULL, -- Some reasonable character limit
)
Ви можете перелічити всі доступні типи даних для творців питань, вибравши цю таблицю QuestionDataType. Ваш інтерфейс може посилатися на QuestionDataTypeId, щоб вибрати правильний формат для альтернативного поля відповіді. Ви не обмежені типами даних TSQL, тому "Номер телефону" може бути типом даних, і ви отримаєте відповідне форматування / маскування в інтерфейсі користувача. Також, якщо потрібно, ви можете передати свої дані відповідним типам за допомогою простого твердження справи, щоб здійснити будь-яку обробку (вибір, перевірку тощо) на альтернативні відповіді.