Sql Rails基于行的数据库,请求数量巨大
我设计了一个以短链接行为中心的数据库 我有以下模式:Sql Rails基于行的数据库,请求数量巨大,sql,ruby-on-rails,ruby,database,postgresql,Sql,Ruby On Rails,Ruby,Database,Postgresql,我设计了一个以短链接行为中心的数据库 我有以下模式: create_table "students", force: :cascade do |t| t.string "first_name" t.string "last_name" t.string "email" t.boolean "recruit", default: true t.boolean "archive", default: false t.da
create_table "students", force: :cascade do |t|
t.string "first_name"
t.string "last_name"
t.string "email"
t.boolean "recruit", default: true
t.boolean "archive", default: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "fields", force: :cascade do |t|
t.string "name"
t.integer "index"
t.integer "group_id"
t.string "description"
t.string "options"
t.boolean "hidden"
t.boolean "locked", default: false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "groups", force: :cascade do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "texts", force: :cascade do |t|
t.integer "student_id"
t.integer "field_id"
t.string "content", default: ""
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "options", force: :cascade do |t|
t.integer "student_id"
t.integer "field_id"
t.string "choice", default: ""
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "addresses", force: :cascade do |t|
t.integer "student_id"
t.integer "field_id"
t.string "address_1", default: ""
t.string "address_2", default: ""
t.string "city", default: ""
t.integer "state_id", default: 1
t.string "zip", default: ""
t.datetime "created_at"
t.datetime "updated_at"
end
这个组织的基础是完全灵活的形式。您只需在字段表中添加一个新行,该条目在生成学生的表单上定义一个新问题。组是指选项字段、文本字段或地址。保存数据时,与给定字段关联的组会告诉我的应用程序将其放入哪个表中。这个系统运行得很好。它非常灵活,我可以很容易地看到学生对某些选项有哪些数据,并且我可以基于几乎任何东西进行查询
问题是当我开始展示学生时。我首先查询要显示的学生,然后搜索每个学生的每个字段。这意味着对于500名学生,我有大约2500个关于基本表单的查询。这会影响性能
我想知道将查询连接在一起并加速这个系统的最佳方法是什么
问题的一部分是,我不能100%确定某个学生有一个给定的字段,所以当我现在查询时,如果数据库没有返回结果,我就可以创建一个 这里似乎没有定义任何外键。使用FK和确保它们命中每个表上的索引的组合应该允许快速联接 我假设您使用的是基于Rails和DSL的ActiveRecord。我建议在添加FK后使用联接 如果您担心某些联接列不存在,那么可以在调用联接时使用上面链接中提到的左外部联接,这样即使联接条件不匹配,您仍然可以从左侧表中获取所有行,只需获取右侧的空列值即可。空值将告诉您哪些不存在,可能需要随后创建 根据OP的评论进行编辑: 我自己没有使用过SchemaPlus gem,但我认为如果您愿意,可以将其用于外键,因为这是它所支持的东西之一 关于这个问题: 比如,如果您认为它是外键,是否会导致问题 某个原因导致数据在一端不再存在 外键是强制执行的关键 例如,如果您在文本表中将字段_id作为外键,则在不使用级联删除下游记录的情况下,无法从字段表中删除相应的记录,因为它引用的是字段中的记录 另一方面,您将无法在文本中插入字段id无效的行-如果字段中不存在字段id,Postgres将抛出外键约束冲突 外键是表设计的关键部分,必须加以利用。它使您无需将所有逻辑放在应用程序代码中的所有位置,例如,在尝试插入任何内容之前,必须检查要插入的密钥是否有效;相反,如果不是这样,Postgres将违反约束,这将作为可以处理的异常返回到您的应用程序,例如回滚和返回错误 基本上,当一个表中的id引用另一个表中的记录时,应该在外键约束中定义该id
此外,可能值得为每个表添加一个主键。我经常喜欢使用一个串行变量来确保每一行都可以通过一个键来识别,即使存在构成隐含主键的元组。主键还基于这些键隐式创建索引。Hi。我一直在研究SchemaPlus gem,它似乎是添加外部约束作为一个简单的约定,我可以在迁移中使用它。把所有我想成为外键的栏目都正式设置为外键有什么问题吗?如果由于某种原因数据在一端不再存在,那么认为它是外键会导致问题吗?我有一些行将引用我的主用户表,可以是一个键,但它们也可以被删除。外键在删除时会引起连锁反应吗?