逻辑数据库设计 - 多列属性(多列转行)

  假设有一个要开发一个试题系统,全是不定项选择题。一道题可能有2,3,4...个答案,数据应如何设计呢?本处旨在说明问题所在,例如同类问题还有存储电话,一我的可能有多个号码等等。javascript

1、存储多值属性

  反模式:建立多个列。html

  咱们知道每列最好只存储一个值,所以先看以下设计:java

复制代码
  CREATE TABLE Question(
      QuestionId int   PK,
      QuestionBody nvarchar(500),
      Answer1  nvarchar(500),
      Answer2  nvarchar(500),
      Answer3  nvarchar(500),
      Answer4  nvarchar(500)
  )
复制代码

  相似上面的设计,假设答案只有两个,那么后面的两个Answer3,Answer4就为NULL,展现表以下:git

  

  这是很传统的属性设计,致使即便如今很简单的任务也变得很简单了!数据库

  一、查询数据数据库设计

  假设有一道题的答案出错了,可是你只记得答案。post

SELECT * FROM Question WHERE 
    Answer1 = '猪有4条腿'
    OR Answer2 = '猪有4条腿'
    OR Answer3 = '猪有4条腿'
    OR Answer4 = '猪有4条腿'

  显示结果以下:this

  

  假如,另外也有一道题目,也有一个答案猪有3条腿,那么你要查得这条数据,就须要这样:spa

SELECT * FROM Question WHERE 
    (Answer1 = '猪有4条腿' OR Answer2 = '猪有4条腿' OR Answer3 = '猪有4条腿' OR Answer4 = '猪有4条腿')
    AND
    (Answer1 = '猪有3条腿' OR Answer2 = '猪有3条腿' OR Answer3 = '猪有3条腿' OR Answer4 = '猪有3条腿')

  怎么样又长又臭吧!不怕,哥安慰下你,其实有简单点的方法:设计

  SELECT * FROM Question WHERE 
      '猪有3条腿' IN (Answer1,Answer2,Answer3,Answer4)
      AND
      '猪有4条腿' IN (Answer1,Answer2,Answer3,Answer4)

  怎么样短了不少吧,相信你也仍是不会卖账。

  二、添加、更新以及删除值

  在以上设计中,假设我要删除答案'猪有3条腿'的SQL语句怎么写呢?你们被考到了吧。

  UPDATE Question
      SET Answer1 = NULLIF(Answer1,'猪有3条腿'),
          Answer2 = NULLIF(Answer2,'猪有3条腿'),
          Answer3 = NULLIF(Answer3,'猪有3条腿'),
          Answer4 = NULLIF(Answer4,'猪有5条腿')
  WHERE QuestionId = 2

  添加一个答案,更新一个答案都有点难写, 有兴趣的朋友能够本身敲敲。

  三、确保惟一性

  如何确保同一个值不出如今多个列中,即有可能你并不想一道题中有两个答案是同样的。咱们很难阻止重复的答案出现,由于Unique只能用于行。

  四、值在不断增加

  当咱们有一道题有5个答案的时候,悲剧,你要更改表结构了。

  以上种种问题说明,以上设计根本不堪一击。

2、解决方案 - 从属表

  问题的根源在于:存储一个具备多个值的属性。对于以上设计,若是每道题都规定是4个答案,以上设计是能够用的。问题在于,答案个数不肯定。

  所以,咱们须要建立一个从属表,将不肯定个数的值提取出来做为行存储,而不是列。

  整体设计以下:

复制代码
CREATE TABLE Question(
    QuestionId    int    PK,
    QuestionBody Body nvarchar(500)
)

CREATE TABLE Answer(
    AnswerId    int    PK,
    AnswerBody    nvarchar(500),
    QuestionId    int,
    FOREIGN KEY(QuestionId) REFERENCES Question(QuestionId)
)
复制代码

  对于以上设计,多少个答案都没问题了,并且增删查改都简单了不止一个档次。

  其实,只不过是一个一对多的关系。并且这个问题很容易一眼就看出,不过变种问题你却未必会条件反应式地提出同样从属表。

 

 
 
 
0
0
 
(请您对文章作出评价)
 
« 上一篇: IBatis.Net 表链接查询(五)
» 下一篇: 逻辑数据库设计 - 元数据分裂(分区表)
相关文章
相关标签/搜索