根据您所说的,我将使用以下一般模式:
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表中。回答问题的第二个用户将从一个答案列表中选择(是/否= 2个列表)。如果合适,您还可以展开PollQuestion表以包括创建者的用户ID,以便跟踪他们创建的问题。
在您的UI上,用户选择的答案可以绑定到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的各种数据类型。las,我们没有生活在一个完美的世界中。我能想到的最好的折衷方法是在PollQuestion表中指定AlternateResponse数据类型应该是什么,并将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表中进行选择,您可以列出问题创建者的所有可用数据类型。您的UI可以引用QuestionDataTypeId为替代响应字段选择正确的格式。您不仅限于TSQL数据类型,因此“电话号码”可以是数据类型,并且您将在UI上获得适当的格式/掩码。另外,如果需要,您可以通过简单的case语句将数据转换为适当的类型,以便对替代答案进行任何类型的处理(选择,验证等)。