Com base no que você disse, eu usaria o seguinte esquema geral:
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])
)
Você realmente não se importa se a resposta é um número, data, palavra etc. etc. porque os dados são uma resposta a uma pergunta e não algo em que você precisa operar diretamente. Além disso, os dados só têm significado no contexto da questão. Como tal, o nvarchar é o mecanismo legível por humanos mais versátil para armazenar os dados.
A pergunta e as respostas em potencial seriam reunidas do primeiro usuário e inseridas nas tabelas PollQuestion e PollOption. O segundo usuário que responde às perguntas selecionaria em uma lista de respostas (verdadeiro / falso = lista de 2). Você também pode expandir a tabela PollQuestion para incluir o ID do usuário do criador, se apropriado, para rastrear as perguntas que ele cria.
Na sua interface do usuário, a resposta que o usuário seleciona pode ser vinculada ao valor PollOptionId. Juntamente com o PollQuestionId, você pode verificar se a resposta é válida para a pergunta rapidamente. Sua resposta, se válida, seria inserida na tabela PollResponse.
Existem alguns problemas em potencial, dependendo dos detalhes do seu caso de uso. Se o primeiro usuário quiser usar uma pergunta matemática, e você não quiser oferecer várias respostas possíveis. Outra situação é se as opções que o usuário inicial fornece não são as únicas opções que o segundo usuário pode escolher. Você pode refazer esse esquema da seguinte maneira para suportar esses casos de uso adicionais.
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])
)
Eu provavelmente adicionaria uma restrição de verificação para garantir que uma opção seja fornecida ou uma resposta alternativa, mas não ambas (opção e resposta alternativa), dependendo de suas necessidades.
Editar: tipo de dados de comunicação para AlternateResponse.
Em um mundo perfeito, poderíamos usar o conceito de genéricos para lidar com vários tipos de dados para o AlternateReponse. Infelizmente, não vivemos em um mundo perfeito. O melhor compromisso que posso pensar é especificar qual deve ser o tipo de dados AlternateResponse na tabela PollQuestion e armazenar o AlternateReponse no banco de dados como um nvarchar. Abaixo está o esquema de perguntas atualizado e a nova tabela de tipos de dados:
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
)
Você pode listar todos os tipos de dados disponíveis para criadores de perguntas, selecionando nesta tabela QuestionDataType. Sua interface do usuário pode fazer referência ao QuestionDataTypeId para selecionar o formato apropriado para o campo de resposta alternativo. Você não está limitado aos tipos de dados TSQL; portanto, "Número de telefone" pode ser um tipo de dados e você receberá uma formatação / máscara apropriada na interface do usuário. Além disso, se necessário, você pode converter seus dados nos tipos apropriados por meio de uma simples declaração de caso, a fim de executar qualquer tipo de processamento (seleção, validação etc.) nas respostas alternativas.