有关mysql联表的拆分

1138 查看

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

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

在最开始,先解释一年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'];

}

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

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