何时分隔数据库列含义(通用列)
When to seperate database column meaning (generic columns)
我正在为一个大约有 20 个问题的网站设计一个反馈系统,但这些问题每年都可能发生变化,并试图考虑最佳设计。
最简单的方法是将每个问题映射到一个列中,但这需要每年创建一个新的 table 并更改根本不明智的应用程序代码。
第二个选项是将列与含义分开,并有第二个 table 应用含义,即
Table1: (row per survey) Table2: (row per questionnaire type)
QuestionID AnswerID
Question1 QuestionID
Question2 Answer1
... ....
Question20 Answer20
我能想到的第三种选择是将各个方面完全分开,例如:
Table1: Table2: Table3: Table4:
QuestionID AnswerID MatchTableID SetID
QuestionValue AnswerValue QuestionID FeedbackSet
AnswerID QuestionID
这给它带来了可扩展性的好处,但是对于几百条记录每年最多更改一次的东西来说可能是过多的,我不确定这是否感觉有点像实体-属性值设计。
对于什么被认为是这里的最佳实践以及什么被认为是接受table实践的任何评论,我将不胜感激。
您可能只想保持简单并使用经典的关系设置。
模特:
class Question < ActiveRecord::Base
has_many :replies
has_many :answers
belongs_to :questionnaire
end
class Answer < ActiveRecord::Base
belongs_to :question
has_many :replies
end
# A collection of questions
class Questionnaire < ActiveRecord::Base
has_many :questions
has_many :replies, through: :questions
end
# A user reply to a question
# acts as a many to many join table
class Reply < ActiveRecord::Base
belongs_to :question
belongs_to :answer
end
架构:
ActiveRecord::Schema.define(version: 20160215124045) do
create_table "answers", force: :cascade do |t|
t.text "text"
t.integer "question_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "answers", ["question_id"], name: "index_answers_on_question_id"
create_table "questionnaires", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "questions", force: :cascade do |t|
t.text "text"
t.integer "questionnaire_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "questions", ["questionnaire_id"], name: "index_questions_on_questionnaire_id"
create_table "replies", force: :cascade do |t|
t.integer "question_id"
t.integer "answer_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "replies", ["answer_id"], name: "index_replies_on_answer_id"
add_index "replies", ["question_id"], name: "index_replies_on_question_id"
end
是的,它有很多 tables - 但这为您提供了很大的灵活性,而无需处理键值 tables 的麻烦。而且它的构建速度也比对动态模式的一些骇人听闻的尝试快得多。
如果需要,提取指标也非常容易。
这个例子做了很多假设:
- 这些问题是多项选择 - 不是写入。您可以通过将写入存储在回复中来非常简单地调整它 table。
- 问题与问卷是一对一的关系。使用联接 table 和 HABTM 关系或
has_many through:
如果需要能够在多个问卷中重复使用问题。
我正在为一个大约有 20 个问题的网站设计一个反馈系统,但这些问题每年都可能发生变化,并试图考虑最佳设计。
最简单的方法是将每个问题映射到一个列中,但这需要每年创建一个新的 table 并更改根本不明智的应用程序代码。
第二个选项是将列与含义分开,并有第二个 table 应用含义,即
Table1: (row per survey) Table2: (row per questionnaire type)
QuestionID AnswerID
Question1 QuestionID
Question2 Answer1
... ....
Question20 Answer20
我能想到的第三种选择是将各个方面完全分开,例如:
Table1: Table2: Table3: Table4:
QuestionID AnswerID MatchTableID SetID
QuestionValue AnswerValue QuestionID FeedbackSet
AnswerID QuestionID
这给它带来了可扩展性的好处,但是对于几百条记录每年最多更改一次的东西来说可能是过多的,我不确定这是否感觉有点像实体-属性值设计。
对于什么被认为是这里的最佳实践以及什么被认为是接受table实践的任何评论,我将不胜感激。
您可能只想保持简单并使用经典的关系设置。
模特:
class Question < ActiveRecord::Base
has_many :replies
has_many :answers
belongs_to :questionnaire
end
class Answer < ActiveRecord::Base
belongs_to :question
has_many :replies
end
# A collection of questions
class Questionnaire < ActiveRecord::Base
has_many :questions
has_many :replies, through: :questions
end
# A user reply to a question
# acts as a many to many join table
class Reply < ActiveRecord::Base
belongs_to :question
belongs_to :answer
end
架构:
ActiveRecord::Schema.define(version: 20160215124045) do
create_table "answers", force: :cascade do |t|
t.text "text"
t.integer "question_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "answers", ["question_id"], name: "index_answers_on_question_id"
create_table "questionnaires", force: :cascade do |t|
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "questions", force: :cascade do |t|
t.text "text"
t.integer "questionnaire_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "questions", ["questionnaire_id"], name: "index_questions_on_questionnaire_id"
create_table "replies", force: :cascade do |t|
t.integer "question_id"
t.integer "answer_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
add_index "replies", ["answer_id"], name: "index_replies_on_answer_id"
add_index "replies", ["question_id"], name: "index_replies_on_question_id"
end
是的,它有很多 tables - 但这为您提供了很大的灵活性,而无需处理键值 tables 的麻烦。而且它的构建速度也比对动态模式的一些骇人听闻的尝试快得多。
如果需要,提取指标也非常容易。
这个例子做了很多假设:
- 这些问题是多项选择 - 不是写入。您可以通过将写入存储在回复中来非常简单地调整它 table。
- 问题与问卷是一对一的关系。使用联接 table 和 HABTM 关系或
has_many through:
如果需要能够在多个问卷中重复使用问题。