foreach 避免循环体内查询数据表



1.问题

在开发中有很多 foreach 循环中查询数据库的操作

为了避免循环中多次链接数据库造成开销

使用 mysql in 操作将数据都查询出来,转换 map,然后通过 key 去数组中匹配


2.场景

  1. 如通过关系表ID查询 middle 表中 id, user_id,company_id

    再用user_id查询用户名称,company_id查询公司名称

// 关系表的 ID
$data = array(
    array(
        'id' => 8,
    ),
    array(
        'id' => 2,
    ),
);

  1. 简单情况,循环中存在大量数据库链接查询
// 栗子
foreach ($data as $k=>$v) {

    $sql0 = "select id, user_id, company_id from middle where id $v['id']"
    $sql1 = "select username from user where id = $sql0['user_id'] ";
    $sql2 = "select company_name from company where id = $sql0['company_id'] ";
    
    $array[] = [
        'user_name' =>  $sql1['username'],
        'company_name' =>  $sql2['company_name'],
    ]
}

 只表达意思,不要注重细节


3.解决

  1. 将 middleTable 表中 user数据使用 in 查询出来。公司同理。查询结果如下
// 关系表
$middleTable = array(
    array(
        'id' => 8,
        'user_id' => '29',
        'company_id' => '100',
    ),
    array(
        'id' => 2,
        'user_id' => '42',
        'company_id' => '200',
    ),
);

// user 表数据
$user = array(
    array(
        'id' => '29',
        'nick_name' => '提莫',
    ),
    array(
        'id' => '42',
        'nick_name' => '娜可露露',
    ),
);

// company 表数据
$company = array(
    array(
        'id' => 100,
        'company_name' => '英雄联盟',
    ),
    array(
        'id' => 200,
        'company_name' => '王者荣耀',
    ),
);

  1. 将 关系表,user 表,company 表数据转为map,为了在循环时进行 key 匹配
$middle_map = array(

    '8' => array(
        'id' => 8,
        'user_id' => '29',
        'company_id' => '100',
    ),
    '2' => array(
        'id' => 2,
        'user_id' => '42',
        'company_id' => '200',
    ),
);

$user_map = array(
    '29' => array(
        'id' => '29',
        'nick_name' => '提莫',
    ),
    '42' => array(
        'id' => '42',
        'nick_name' => '娜可露露',
    ),
);

$company_map = array(
    '100' => array(
        'id' => 100,
        'company_name' => '英雄联盟',
    ),
    '200' => array(
        'id' => 200,
        'company_name' => '王者荣耀',
    ),
);


  1. 将 $v 中的 id 去上面各个 map 中匹配
$reqItem = array();
foreach($data as $k=>$v) {
  
    $reqItem[] = array(
        'name' => $user_map[$middle_map[$v['id']]['user_id']]['nick_name'],
        'company' => $company_map[$middle_map[$v['id']]['company_id']]['company_name'],
    );
}

  1. 最终结果
Array
(
    [0] => Array
        (
            [name] => 提莫
            [company] => 英雄联盟
        )

    [1] => Array
        (
            [name] => 娜可露露
            [company] => 王者荣耀
        )
)

上一篇:1.5小时!一键部署Oracle 11GR2 RAC 集群


下一篇:组合模式学习