我正在构建一个用于存储问题和答案的数据库。到目前为止,有各种问题类型与DateTime答案,自由文本,DropDownList以及链接到数据库中其他表的一些问题类型相关。我的设计问题是:某些问题类型具有该类型唯一的其他布尔属性。在通用的Questions表中使用boolean列或为每个问题类型创建某种Flag表是否更好?
例如,DropDownList Question可能有一个布尔属性来判断当选择值“Other”时是否显示TextBox,但是Free Text Question对此没用。
谢谢堆
编辑:
我想它似乎正在沸腾到最好是将未使用的列存储在一个通用的Questions表中,以扩展每个Question类型,并使用Views访问各种问题的数据,将大量的键返回到Question表中类型。
答案 0 :(得分:2)
从基本问题表中删除所有额外属性,并为“问题类型”提供一个字段,并为每个问题类型提供一组表。在应用程序代码中,基于问题类型从特定问题类型表中检索行并使用它们。
一个例子:
基本问题表:t_question <QuestionID, Question, QuestionType, QuestionTypeLink>
假设您有两种问题类型:Comprehensive
或Simple
。使用架构为每个表创建两个表:t_compflags <linkID, field1, field2...>
和t_simpleflags <linkID, field1, field2...>
。
现在在基本问题表中,QuestionType
将采用两个值:Comprehensive
或Simple
。基于该字段,它使用QuestionTypeLink
来引用任一表中的行。
编辑:
您无法在这些标签上直接强制执行PK-FK约束,您必须在应用程序代码中执行此操作。但是如果你想强制执行这个约束,就会有一种肮脏的方式。而不是QuestionTypeLink
,有两列CompQuestionTypeLink
和SimpQuestionTypeLink
,它们允许空值并引用其他两个表。但我个人认为这是一个糟糕的设计。
答案 1 :(得分:0)
这完全取决于您想要做多少规范化以及您正在讨论的列数。
如果您期望得到相当多的数字,那么您应该只有1:1的表关系来扩展该问题类型。像
这样的东西创建表QuestionType_DropDownList
(OtherDisplay位,
SomethingElse bit)
这更容易阅读,更容易查询。但它不容易维护。不幸的是,这是一个优点/缺点。
根据我的经验,我会选择这个解决方案,因为你永远不知道未来会怎样。
答案 2 :(得分:0)
根据您拥有的组合数量,您可以将每种组合表达为自己的类型:
DateTime
DropDownList
DropDownListWithOptionalOther
FreeText
FreeTextNumbersOnly
...
这会以一种潜在的组合爆炸为代价而稍稍压平你的设计。但我不知道你有多少种组合,或者将会有多少组合。
如果DropDownList选项为“其他”,您是否可以自动包含文本框?或者是否会出现用户不必指定“其他”的情况?
如果你有太多的组合要考虑,那么你仍然需要在每个问题的基础上指定标志,所以在Questions表中包含另一个字段以指定这些标志是有意义的。也许将它们作为纯文本,以便您可以在以后需要延长?就像该字段中以逗号分隔的标志列表一样?
答案 3 :(得分:0)
我正在考虑将其作为一种可能的解决方案,对我来说似乎更抽象,并允许最后的扩展。
CREATE TABLE dbo.QuestionTypes
(
Id INT IDENTITY(1, 1) PRIMARY KEY,
Type VARCHAR(256) NOT NULL
);
CREATE TABLE dbo.TypeSpecificFlags
(
Id INT IDENTITY(1, 1) PRIMARY KEY,
TypeId INT REFERENCES dbo.QuestionTypes(Id) NOT NULL,
Flag VARCHAR(256) NOT NULL
)
CREATE TABLE dbo.Questions
(
Id INT IDENTITY(1, 1) PRIMARY KEY,
Name VARCHAR(256) NOT NULL,
ShortName VARCHAR(32),
TypeId INT REFERENCES QuestionTypes(Id) NOT NULL,
AllowNulls BIT NOT NULL DEFAULT 1,
Sort INT
);
CREATE TABLE dbo.QuestionsFlags
(
Id INT IDENTITY(1, 1) PRIMARY KEY,
QuestionId INT REFERENCES dbo.Questions(Id) NOT NULL,
FlagId INT REFERENCES dbo.TypeSpecificFlags(Id) NOT NULL,
Answer BIT NOT NULL
);