资讯专栏INFORMATION COLUMN

有关mysql联表的拆分

evin2016 / 2473人阅读

摘要:有挫败感,故现在把联表的拆分写一篇文章。在最开始,先解释一年的联表查询的机制。现在又三张表基础信息扩展信息银行存款现在需要取出每个会员的基本信息,扩展信息以及银行存款。最好的办法就是对这个进行拆分。

今天有朋友问了我一个问题,说:

有四张表,他要从四张表里面取数据,他已经设计好了数据冗余等等,但还是需要通过联表查询来获取数据,问我有没有比较好的解决办法。说了挺长时间,朋友没听明白。有挫败感,故现在把联表的拆分写一篇文章。

在最开始,先解释一年mysql的联表查询的机制。

当前 mysql 执行的关联策略很简单:mysql对任何关联都执行嵌套循环关联操作,即:Mysql先在一个表中取出单条数据,然后在嵌套到下一个表中寻找匹配的行,依次下去,直到找到所有表中匹配的行为止,然后根据各个表匹配的行,返回查询中需要得各个列。mysql会尝试在最后一个关联表中找到所有匹配的行,如果最后一个关联表无法找到更多的行以后,mysql返回到上一层次关联表,看能否能够找到更多的匹配记录。一次类推迭代执行。当然实际的mysql操作没这么简单,这里只是说一个大概的流程。

举例说明:

现有一个sql语句:
select table-1.col1,table-2.col2 from table-1 inner join table-2 using(col3) where table-1.col1 in (5,6)

这个sql的简单流程如

  

outer_iter = select col1,col3 from tables-1 where col1 in(5,6)
outer_row = outer_iter.row

while outer_row

inner_iter = select col2,col3 from table-2 where col3 = ourer_row.col3

inner_row = inner_iter.row

while inner_row

   output [ outer_row.col1,inner_row.col2]

   inner_row = inner_iter.next

end

outer_row = outer_iter.next
end

回归正题,因为mysql的这种机制和其他数据库的hash配对不一样,效率比较低,所以要尽量避免使用联表查询来获取数据,而且mysql在设计上让连接和断开连接都很轻量级,在返回一个小结果很高效。

现在说一下怎么拆分sql。

现在又三张表:

user 基础信息

uid username mobile
10 tree 110
11 Hot 112
userinfo 扩展信息

uid qq weibo
10 123 Tree.blog
11 456 hot.blog
money 银行存款

uid money
10 10000
11 20000
现在需要取出每个会员的基本信息,扩展信息以及银行存款。如果用联表查询的话,你可能写出这样的语句

select * from user left join userinfo on user.uid=userinfo.uid left join money on user.uid=money.uid

实际情况中可能比这个要复杂的多,数据量越大这条sql可能问题越大。尤其在高并发的情况下更糟糕。最好的办法就是对这个sql进行拆分。

简单的拆分过程如下:

先取出user表中的数据,取出结果为(模拟php取出过程)

user => array(

0 -> [ uid:10,username:tree,mobile:110]

1-> [uid:11,username:hot,mobile:112]

)

然后取出userinfo里面的数据:

userinfo => array(

0 -> [uid:10,qq:123,weibo:tree.blog]

1-> [uid:11,qq:456,weibo:hot.blog]

)

然后循环 user数组,将uid 平常逗号隔开的串,10,11。将10,11用in查询取出userinfo

接下来需要循环userinfo数组,用uid作为Key,变成如下格式:

userinfo => array(

10 => [uid:10,qq:123,weibo:tree,blog]

11 => [uid:10,qq:456,weibo:hot.blog]

)

下面是重点:

循环user数据,结果应该是这样:

foreach($user as $key=>$row){

    $user[$key]["qq"] = $userinfo[$row["uid"]]["qq"];

    $user[$key]["weibo"] = $userinfo[$row["uid"]]["weibo"];

}

这样就能取出所需要得数据了。

今天就先到这里。明天再补充一部分内容。这只是一个很简单的介绍,这种思路可以延伸出很多不同的用法.

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/20789.html

相关文章

  • 有关mysql表的拆分

    摘要:有挫败感,故现在把联表的拆分写一篇文章。在最开始,先解释一年的联表查询的机制。现在又三张表基础信息扩展信息银行存款现在需要取出每个会员的基本信息,扩展信息以及银行存款。最好的办法就是对这个进行拆分。 今天有朋友问了我一个问题,说: 有四张表,他要从四张表里面取数据,他已经设计好了数据冗余等等,但还是需要通过联表查询来获取数据,问我有没有比较好的解决办法。说了挺长时间,朋友没听明白。有...

    FrancisSoung 评论0 收藏0
  • MySQLMySQL分区与传统的分库分表

    摘要:传统的分库分表传统的分库分表都是通过应用层逻辑实现的,对于数据库层面来说,都是普通的表和库。分区也存在与传统分表一样的问题,可扩展性差。子分区子分区是分区表中每个分区的再次分割。查询优化分区的目的是为了 传统的分库分表 传统的分库分表都是通过应用层逻辑实现的,对于数据库层面来说,都是普通的表和库。 分库 分库的原因 首先,在单台数据库服务器性能足够的情况下,分库对于数据库性能是没有影响...

    xuexiangjys 评论0 收藏0
  • Mysql - JOIN详解

    摘要:如果之前对不同的执行结果没有概念,可以结合这篇文章往下看的执行顺序以下是查询的通用结构它的执行顺序如下语句里第一个被执行的总是子句对左右两张表执行笛卡尔积,产生第一张表。 0 索引 JOIN语句的执行顺序 INNER/LEFT/RIGHT/FULL JOIN的区别 ON和WHERE的区别 1 概述 一个完整的SQL语句中会被拆分成多个子句,子句的执行过程中会产生虚拟表(vt)...

    antz 评论0 收藏0
  • Mysql - JOIN详解

    摘要:如果之前对不同的执行结果没有概念,可以结合这篇文章往下看的执行顺序以下是查询的通用结构它的执行顺序如下语句里第一个被执行的总是子句对左右两张表执行笛卡尔积,产生第一张表。 0 索引 JOIN语句的执行顺序 INNER/LEFT/RIGHT/FULL JOIN的区别 ON和WHERE的区别 1 概述 一个完整的SQL语句中会被拆分成多个子句,子句的执行过程中会产生虚拟表(vt)...

    Jioby 评论0 收藏0
  • Mysql - JOIN详解

    摘要:如果之前对不同的执行结果没有概念,可以结合这篇文章往下看的执行顺序以下是查询的通用结构它的执行顺序如下语句里第一个被执行的总是子句对左右两张表执行笛卡尔积,产生第一张表。 0 索引 JOIN语句的执行顺序 INNER/LEFT/RIGHT/FULL JOIN的区别 ON和WHERE的区别 1 概述 一个完整的SQL语句中会被拆分成多个子句,子句的执行过程中会产生虚拟表(vt)...

    glumes 评论0 收藏0

发表评论

0条评论

evin2016

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<