数据库设计 - 可选位字段

时间:2010-12-13 20:52:30

标签: sql database-design

我正在构建一个用于存储问题和答案的数据库。到目前为止,有各种问题类型与DateTime答案,自由文本,DropDownList以及链接到数据库中其他表的一些问题类型相关。我的设计问题是:某些问题类型具有该类型唯一的其他布尔属性。在通用的Questions表中使用boolean列或为每个问题类型创建某种Flag表是否更好?

例如,DropDownList Question可能有一个布尔属性来判断当选择值“Other”时是否显示TextBox,但是Free Text Question对此没用。

谢谢堆

编辑:

我想它似乎正在沸腾到最好是将未使用的列存储在一个通用的Questions表中,以扩展每个Question类型,并使用Views访问各种问题的数据,将大量的键返回到Question表中类型。

4 个答案:

答案 0 :(得分:2)

从基本问题表中删除所有额外属性,并为“问题类型”提供一个字段,并为每个问题类型提供一组表。在应用程序代码中,基于问题类型从特定问题类型表中检索行并使用它们。

一个例子:

基本问题表:t_question <QuestionID, Question, QuestionType, QuestionTypeLink>

假设您有两种问题类型:ComprehensiveSimple。使用架构为每个表创建两个表:t_compflags <linkID, field1, field2...>t_simpleflags <linkID, field1, field2...>

现在在基本问题表中,QuestionType将采用两个值:ComprehensiveSimple。基于该字段,它使用QuestionTypeLink来引用任一表中的行。

编辑:

您无法在这些标签上直接强制执行PK-FK约束,您必须在应用程序代码中执行此操作。但是如果你想强制执行这个约束,就会有一种肮脏的方式。而不是QuestionTypeLink,有两列CompQuestionTypeLinkSimpQuestionTypeLink,它们允许空值并引用其他两个表。但我个人认为这是一个糟糕的设计。

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