mysql和java多表join业务优化?

写作业的思考。假如有这么一个签到系统

按照范式设计有

学院表
课表(学院课表一对多)
老师表
学生表
教课表(老师课表多对多)
上课表(学生课表多对多)
排课表(课表排课一对多)
签到表(排课签到一对多)
签到记录表(签到,签到记录一对多)

假如设定两个查询
学生由学号和课号查询签到
教师由教工号和课号查询

而在我实现这个系统时,随便一个查询动作都建立了好多张表,为了获取排课,课程,老师,学院信息。

我觉得这样做,,有点麻烦?可是把它放到代码实现也要不断发起查询很多次呀。。

比如这是我刚刚写的,,一个获取这个学生本周需要签到的课程,我想看看瞎几把写可以联立成什么样子,。功能的目的我达到了

        SELECT
        att.user_usr_id, att.course_coz_id,
        sch.sch_id, sch.sch_year, sch.sch_term, sch.sch_start_week, sch.sch_end_week,
        sch.sch_fortnight, sch.sch_day, sch.sch_start_time, sch.sch_end_time, sch.course_coz_id, sch.location_loc_id,
        loc.loc_id, loc.loc_name,
        coz.coz_id, coz.coz_name, coz.coz_size, coz.coz_act_size, coz.coz_att_rate,
        tea.user_usr_id tea_user_usr_id, tea.course_coz_id,
        tch.usr_name tea_user_usr_name,
        coz_sch.sch_id coz_sch_id, coz_sch.sch_year coz_sch_year, coz_sch.sch_term coz_sch_term,
        coz_sch.sch_start_week coz_sch_start_week, coz_sch.sch_end_week coz_sch_end_week, coz_sch.sch_fortnight
        coz_sch_fortnight,
        coz_sch.sch_day coz_sch_day, coz_sch.sch_start_time coz_sch_start_time, coz_sch.sch_end_time coz_sch_end_time,
        coz_sch.course_coz_id coz_sch_course_coz_id, coz_sch.location_loc_id,
        coz_sch_loc.loc_id coz_sch_loc_id, coz_sch_loc.loc_name coz_sch_loc_name,
        si_id, si_week, si_time, si_auto,
        sir_id, sir_time, sir_leave, sir_approve, sir_voucher, sir.sign_in_${curYear}_${curTerm}_si_id sir_id,
        sir.user_usr_id sir_user_usr_id
        FROM attendance att
        JOIN schedule sch ON att.course_coz_id = sch.course_coz_id
        LEFT OUTER JOIN location loc ON loc.loc_id = sch.location_loc_id
        <!-- sch coz -->
        JOIN course coz ON sch.course_coz_id = coz.coz_id
        LEFT OUTER JOIN teaching tea ON coz.coz_id = tea.course_coz_id
        LEFT OUTER JOIN schedule coz_sch ON coz.coz_id = coz_sch.course_coz_id
        LEFT OUTER JOIN location coz_sch_loc ON coz_sch.location_loc_id = coz_sch_loc.loc_id
        JOIN user tch ON tea.user_usr_id = tch.usr_id
        <!-- history sign in -->
        JOIN sign_in_${curYear}_${curTerm} si ON sch.sch_id = si.schedule_sch_id
        LEFT OUTER JOIN sign_in_rec_${curYear}_${curTerm} sir ON
        si.si_id = sir.sign_in_${curYear}_${curTerm}_si_id AND
        att.user_usr_id = sir.user_usr_id
        <where>
            sir.sir_id IS NULL <!-- 还没签到de  -->
                AND att.user_usr_id = #{usrId} <!-- 用户id  -->
        </where>
阅读 3.8k
2 个回答

你回写这么多字段,很难说都是当前用户需要的。可以考虑两点建议, 一是可以根据具体查询场景对字段分解下。二是对部分联合查询建立视图,对视图再加上条件查询,业务逻辑更清晰,同时权限也好控制。还有就是对改动不多的字段进行适当冗余,保存在多个表里,这样可以提高查询效率。
个人认为遵守范式前提保证查询效率和开发时间,得到的好处是便于维护和减少存储空间(谁还在乎这个?)。需要做的就是好处和成本之间做均衡。

表关联建议不要超过2张表。可以用代码进行逻辑优化。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题