php遍历多维数据库,PHP代码优化之array_column() 使用(解决循环嵌套Sql的问题)

在开发中,我们会遇到一对多的绑定关系,比如订单:一条订单对应多条商品数据;商品价格:商品价格在不同用户等级或者VIP的价格优惠不同等等。下面以订单为例:

需求: APP订单列表并展示商品信息且需要分页显示数据

常见的做法: 1. 我们根据用户id 获取订单列表(分页数据)后,循环获取每个订单的商品信息,类似以下代码:

public function getOrderList($userId)

{

$orderList = $this->getSaleOrderListByUserId($userId); //获取订单列表 连接数据库查询即可

foreach ($orderList as $index => $item){

$orderList[$index]['goods_list'] = $this->getSaleOrderGoodsInfoByOrderId($item['order_id']); //根据订单id 获取订单商品

}

return $orderList;

}

我们来分析以上代码:

在循环订单列表读取商品列表时,采用了循环的方式,这样需要查询的数据库次数为 count($orderList) + 1 次,如果用户订单数量很多的情况下,就会造成接口请求超时等错误。即使是在有分页的限制情况下,依然会频繁的请求数据库。

那么优化的关键就在于如何减少数据库的请求次数。

思路1:

既然已经获取到了订单列表,是否可以通过mysql 的 in 查询来获取订单的商品条数,再通过代码循环和订单ID(订单表的主键,订单商品表的外键)来匹配呢?

public function getOrderList($userId)

{

$orderList = $this->getSaleOrderListByUserId($userId); //获取订单列表 连接数据库查询即可

$orderGoodsList = $this->getSaleOrderGOodsLists(array_column($orderList, 'order_id')); //根据订单id 获取订单商品 IN查询

foreach ($orderList as $index => $item) {

foreach ($orderGoodsList as $indexs => $items){

if($item['order_id'] == $items['order_id']){

$orderList[$index]['goods_list'][] = $items;

}

}

}

}

来看这段代码,降低了数据库的连接次数,但是在循环时,进行双层循环,复杂度是非常高的,在数据量大的情况下,容易内存溢出。

思路2:

既然已经获取到了订单列表以及订单商品信息, 是否可以将 订单商品信息的数组格式转换为,索引为 order_id 的多维数组呢? 这样,直接使用isset 即可匹配到订单商品信息。

我们来看 array_column() 的第三个参数: index_key:  用作返回数组的索引/键的列, 且第二个参数为NULL时,会返回整个数组,示例:

$a = array(

array(

'id' => 5698,

'first_name' => 'Bill',

'last_name' => 'Gates',

),

array(

'id' => 4767,

'first_name' => 'Steve',

'last_name' => 'Jobs',

),

array(

'id' => 3809,

'first_name' => 'Mark',

'last_name' => 'Zuckerberg',

)

);

var_dump(array_column($a, NULL, 'id'));

输出为:

array(3) {

[5698]=>

array(3) {

["id"]=>

int(5698)

["first_name"]=>

string(4) "Bill"

["last_name"]=>

string(5) "Gates"

}

[4767]=>

array(3) {

["id"]=>

int(4767)

["first_name"]=>

string(5) "Steve"

["last_name"]=>

string(4) "Jobs"

}

[3809]=>

array(3) {

["id"]=>

int(3809)

["first_name"]=>

string(4) "Mark"

["last_name"]=>

string(10) "Zuckerberg"

}

}

所以,我们可以使用array_column() 函数来优化思路1 的代码,如下:

public function getOrderList($userId)

{

$orderList = $this->getSaleOrderListByUserId($userId); //获取订单列表 连接数据库查询即可

$orderGoodsList = $this->getSaleOrderGOodsLists(array_column($orderList, 'order_id')); //根据订单id 获取订单商品 IN查询

$orderGoodsList = array_column($orderGoodsList, NULL, 'order_id');

foreach ($orderList as $index => $item) {

if(isset($orderGoodsList[$item['order_id']])){

$orderList[$index]['goods_list'] = $orderGoodsList[$item['order_id']];

}else{

//此订单无商品

$orderList[$index]['goods_list'] = [];

}

}

}

通过以上代码,我们即降低了代码请求数据库的次数,也降低了代码的复杂度,而且代码也十分的简洁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值