当前位置:Gxlcms > 数据库问题 > 【原】对MYSQL下视图的一些总结

【原】对MYSQL下视图的一些总结

时间:2021-07-01 10:21:17 帮助过:32人阅读

as select id id, PERSON_NAME user_name, ‘PERSON‘ user_type, create_time create_time from T_USER_PERSON UNION ALL select id as id, COMPANY_NAME as user_name, ‘COMPANY‘ as user_type, create_time create_time from T_USER_COMPANY UNION ALL select id as id, ORGANIZATION_NAME as user_name, ‘ORGANIZATION‘ as user_type, create_time create_time from T_USER_ORGANIZATION UNION ALL select id as id, TEAM_NAME as user_name, ‘TEAM‘ as user_type, create_time create_time from T_USER_TEAM;   改变之后的关系图大概是这样的: 技术分享图片

 

  联合查询的sql语句如下: select b.id, b.user_id, v.user_name, b.content from T_BUSSINESS b left join VIEW_ALL_TYPE_USER v ON b.user_id=v.user_id and b.user_type=v.user_type order by b.id desc   看起来很简洁,但是运行起来就慢得要死。其实数据量并不大,用户总共大概有12万,业务数据大概1400条。可是,经过视图和表的关联查询,速度是不可以忍受的,我想,这是多重笛卡尔积的结果吧。   除了联合查询效率低的问题,视图还不能建立索引,没办法有效提高查询效率。   经过再三权衡,我决定放弃视图,宁可使用稍微复杂一些的case-then语句来实现。效果还是可以的。 select b.id, b.user_id, b.user_type, case b.user_type when ‘PERSON‘ then (select USER_NAME from T_USER_PERSON u where u.id=b.user_id) when ‘ENTERPRISE‘ then (select COMPANY_NAME from T_USER_COMPANY o where o.id=b.user_id) when ‘CHARITY‘ then (select ORGANIZATION_NAME from T_USER_ORGANIZATION c where c.id=b.user_id) when ‘TEAM‘ then (select TEAM_NAME from T_USER_TEAM t where t.id=b.user_id) end as user_name, b.content from T_BUSSINESS b order by b.id desc   但是,这样的话,存在一个问题: 如果用别名作为查询条件,会出现错误:Unknown column ‘user_name‘ in ‘where clause‘   1)把别名的查询条件放在table后面: http://bbs.csdn.net/topics/320013418 这种办法对我不起作用,不知道是否是版本的问题……   2)用一个select包起来: http://blog.csdn.net/testcs_dn/article/details/69400269 注意:每个table,包括最终()起来的虚表都要起个别名   3)在查询条件里使用完整的case-then: https://www.cnblogs.com/xiandedanteng/archive/2013/09/22/3333469.html 在本文中的sql语句应该是: select b.id, b.user_id, b.user_type, case b.user_type when ‘PERSON‘ then (select USER_NAME from T_USER_PERSON u where u.id=b.user_id) when ‘ENTERPRISE‘ then (select COMPANY_NAME from T_USER_COMPANY o where o.id=b.user_id) when ‘CHARITY‘ then (select ORGANIZATION_NAME from T_USER_ORGANIZATION c where c.id=b.user_id) when ‘TEAM‘ then (select TEAM_NAME from T_USER_TEAM t where t.id=b.user_id) end as user_name, b.content from T_BUSSINESS b where case b.user_type when ‘PERSON‘ then (select USER_NAME from T_USER_PERSON u where u.id=b.user_id) when ‘ENTERPRISE‘ then (select COMPANY_NAME from T_USER_COMPANY o where o.id=b.user_id) when ‘CHARITY‘ then (select ORGANIZATION_NAME from T_USER_ORGANIZATION c where c.id=b.user_id) when ‘TEAM‘ then (select TEAM_NAME from T_USER_TEAM t where t.id=b.user_id) end like ‘测试%‘ order by b.id desc   -------------------   但是,好景不长,又遇到了问题……   新的需求来了,在外面又多了一层查询: 有多种相似的业务,想要放在一起进行排序展示。(这回我学“聪明”了,不考虑视图了)这样,就需要嵌套两层case-then语句……,先不考虑效率问题,这样冗长的SQL的可读性和维护性也太差了吧?   又经过再三权衡,我还是决定在业务表里增加一个user_name字段,虽然这是个冗余字段,但会使逻辑更简单,更易于维护。至于user_name数据一致性的问题,解决方法有很多:触发器/异步通知/同步更新等等,都可以实现。毕竟user_name并不是经常修改的。 最终的业务表是这样的(当然,其他的业务表也都增加了USER_NAME字段): T_BUSSINESS(ID, USER_ID, USER_TYPE, USER_NAME, CONTENT, ...)   最后看起来大概是这个样子的: 技术分享图片

 

  至少,以我目前有限的认识,这样做是最佳方案,希望有更好方法的同学不吝赐教。        

【原】对MYSQL下视图的一些总结

标签:增加   ati   href   关系图   图片   join   管理所   业务逻辑   提高   

人气教程排行