×

Loading...
Ad by
  • 技多不压身,工到自然成:安省技工证书特训班,点击咨询报名!
Ad by
  • 技多不压身,工到自然成:安省技工证书特训班,点击咨询报名!

想问问这里的大侠们,有一道sql database design难题, 公司有一个网上survery.

本文发表在 rolia.net 枫下论坛以前同事把后台db设计成每一个question answer 都设立一个独立的column.

example
web form
question A
question B
question C
...
question Z

database

table survey

userpk question _A , question_B, question_C ... question_Z

如果问题不多,那也就算了, 但是每年要更新很多questiones 我觉得这样不是一个很好的design

所以我想把它改成
先设立一个题库

table question
pk
question

table survey
userpk questionpk answer

这样可以一劳永逸解决adding column 的难题了。 而且每个table也比较skinny。 但是问题是 answer column data type 不好解决。 some answer 可能只是int 有些就用到varchar(10000)
碰到这种情况我只能把它设置成varchar 最大值。 但很多是浪费的。


所以我想把不同的date type answer 存到不同table里
table survey-int
userpk questionpk answer (int)

table survey-shortstring
userpk questionpk answer(varchar 500)

able survey-longstring
userpk questionpk answer(varchar 5000)

这样可以解决上述问题。 但速度可能要影响。还有generate report时好像比较繁。 好像要用到tabulate什么的

不知那位大侠有没有更好的建议

谢谢更多精彩文章及讨论,请光临枫下论坛 rolia.net
Report

Replies, comments and Discussions:

  • 工作学习 / 专业技术讨论 / 想问问这里的大侠们,有一道sql database design难题, 公司有一个网上survery.
    本文发表在 rolia.net 枫下论坛以前同事把后台db设计成每一个question answer 都设立一个独立的column.

    example
    web form
    question A
    question B
    question C
    ...
    question Z

    database

    table survey

    userpk question _A , question_B, question_C ... question_Z

    如果问题不多,那也就算了, 但是每年要更新很多questiones 我觉得这样不是一个很好的design

    所以我想把它改成
    先设立一个题库

    table question
    pk
    question

    table survey
    userpk questionpk answer

    这样可以一劳永逸解决adding column 的难题了。 而且每个table也比较skinny。 但是问题是 answer column data type 不好解决。 some answer 可能只是int 有些就用到varchar(10000)
    碰到这种情况我只能把它设置成varchar 最大值。 但很多是浪费的。


    所以我想把不同的date type answer 存到不同table里
    table survey-int
    userpk questionpk answer (int)

    table survey-shortstring
    userpk questionpk answer(varchar 500)

    able survey-longstring
    userpk questionpk answer(varchar 5000)

    这样可以解决上述问题。 但速度可能要影响。还有generate report时好像比较繁。 好像要用到tabulate什么的

    不知那位大侠有没有更好的建议

    谢谢更多精彩文章及讨论,请光临枫下论坛 rolia.net
    • Make sure you really understand VARCHAR
      • 我本来觉得varchar是变量, 但是设置varchar时要问你size varchar(500) 我想可能会有区别的,要不然直接就varchar也不用问你具体size了。 如有不对请多多指教。 谢谢
        • 1. I didn't see the varchar column is part of an index. Separating it to two tables with varchar(500) and varchar(5000) won't help anything(performance, storage) but making it complicated.
          • 我的sql 基础不够好,总以为sql server 对 varchar(500) 和 varchar(5000) 会有不同的设置, 比如预留空间什么的。 所以当时我认为varchar(5000)会比较浪费space
            • 如果没有区别,那么所有的列(姓名,性别,部门,……)通通设为varchar(5000)就好了,还要数据库设计干什么?
              • Please explain what the benefit of separating it to two tables is for this case.
                I didn't say you should define varchar(5000) for any varchar column. If you define 性别 as varchar(5000), you can image what problems you may have for the application. For varchar column, just keep the actual max length is fine.
                • 如果“actual max length ”是500,那就没有必要用5000. 这可不是480和500的区别。好处是:存储紧凑,读写速度快。具体到这个应用,那要请楼主举例。
                  • 存储紧凑? VARCHAR500 和VARCHAR5000一样紧存储紧凑. 读写速度快? 两个TABLE怎么能快.
        • 2. Are there any problems for you to store the int answer to the varchar column?
          • 现在想来int是没有太大问题, 可能是text和binary。 这个我可能必须存在另外的table。 因为有时survey里有textbox。 有时会有uploadfile option
            • 我的经验是把不需要检索的东西(二进制文件)放到文件服务器上就好,数据库里最多存个路径、文件名
              • 数据库不只是有检索的功能. 把数据存在FILE SYSTEM上, 会LOSE很多的数据库的功能. 比方说TRANSACTION ROLLBACK的功能. 还有数据BACKUP的问题.
                • 文件要进入数据库之前,必须从客户端上传到FILE SYSTEM; 这时候即使你ROLLBACK, 文件也已经存在。FILE SYSTEM照样可以备份。假如你不在乎开销,把二进制文件存到数据库里当然也没错。
                  • The rollback should backout any changes that were maked within the transaction. The data file can't be backed out from the file system together with database, it is the problem.
                    • 我就是这个意思啊?正因为文件入库前已经上传,ROLLBACK的好处就享受不到了,你照样得手工再删除文件。
                      • You are a lovely kid!
    • 我觉得你的设计没有什么毛病,速度也不会受影响。做个视图把三种answer表 UNION 起来(当然INT要转换为字符串),访问这个视图就像一张表一样。
      • 非常感谢, 想问一下视图是不是view? 我就是没想到用view
        • 视图就是view. 你的table question还要多一个列表明answer是属于哪一种的
          • 对,是应该有一个column 表明answer属于那一种打tata type 谢谢
    • In my humble opinion, you are on the right track. Varchar is used to store strings of variable length. It uses two additional bytes to record the length of the string.
    • You can design database table as the following:.
      You can design database table like the following:

      Tblquestion: questionId int, Question varchar(500).
      tblAnswer: AnswerId int, AnswerTypeID int,Answer varchar(500)
      tblAnswerType; AnswerTypeId, AnswerType
      tblQuestionAnswer: QuestionId int,AnswerId int.

      varchar(500) means you can save 500 characters in this column. each character take one byte.
      if you use unicode, better use nvarchar(1000). each character take two bytes.
      sql server limit max row size is 8061 bytes, it is one page long. even though you can set column length over 8061, you couldn't save data over 8061bytes.
      so if some fields are too long, you can use text and ntext. but affect performance .
      • BTW, you need one more column in tblquestionAnswer, "SpecifiedAnswer text" to save user specified answer, not from the tblanswer
      • 你这设计只是弄了一个题库。答卷本身呢?回答问题的人呢?
        • my design have problem. It should have another table : recordID int, SurveyID,QuestionID,answerID,specifiedAnswer. the previous table "tblQuestionAnswer" changed to questionID,answerID.
          add another table named "tblSurveyQuestion" including SurveyID,QuestionID.
        • I think for this question, there are at least 6 tables as following. please let me know if my
          design still have problem.
          1. tblSurvey , table structure: surveyid, survey_desc..
          2.tblQuestion ,table structure: questionid, question
          3.tblAnswer ,table structure: answerid, answer
          4.tblAnswerType ,table structure; answertypeId, Answertype
          5.tblsurveyQuestion:,table structure: surveyID, questionid
          6.tblquestionAnswer ,table structure: RecordId,surveyID,questionID,answerID,specifiedAnswer
          • tblAnswer: 没有说明是哪个问题的答案?tblAnswerType和其他表完全没有关系。tblquestionAnswer不清楚你想作什么用,是想存用户答案呢,还是想存问题和答案的关系?
    • Don't make it complicated.
      1. If you have to store Int answer to an int column, OneTable: questionID, question, intAnswer int nullable, CharAnswer varchar(5000) nullable.
      If intAnswer is null, then the answer is in CharAnswer column otherwise the answer is in intAnswer column.

      2. If you can store Int answer to a varchar column, OneTable: questionID, question, Answer varchar(5000).