在开发中,我们会遇到一对多的绑定关系,比如订单:一条订单对应多条商品数据;商品价格:商品价格在不同用户等级或者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'] = [];

}

}

}

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

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

  1. server数据库标记为可疑 sql_sqlserver2008数据库被标记为可疑的解决方法.docx

    sqlserver2008数据库被标记为可疑的解决方法.docx SQL Server 2008数据库被标记为可疑 的解决方法 2011-08-23 16:36 佚名 火魔网 字号:T | T 本文我 ...

  2. php无嵌套遍历多维数组,不递归怎么遍历多维数组(维数不定)

    不递归如何遍历多维数组(维数不定) 现有数组 $tree = array ( array ( 'ID' => 1, 'PARENT' => 0, 'NAME' => '祖父', 'C ...

  3. c语言二维数组行优先如何访问快,C/C++遍历二维数组,列优先(column-major)比行优先(row-major)慢,why?...

    C/C++遍历二维数组,列优先(column-major)比行优先(row-major)慢,why? 简单粗暴的答案:存在Cache机制! 稍微啰嗦一点:CPU访问内存(读/写,遍历数组的话主要是读) ...

  4. SQL Server 2008 Analysis Services 多维数据库一步一步从入门到精通

    SQL Server 2008 Analysis Services 多维数据库一步一步从入门到精通(一) 创建 Analysis Services 项目(图) 在开始之前,我的电脑上已经完整的安装了S ...

  5. 二维数组更改vue_使用vue中的v-for遍历二维数组的方法

    如下所示: {{itemss}} 其中,data数据为: this.data = [ [ { type: '', name: '资产', start: '期末余额', end: '期初余额' }, { ...

  6. C++知识点杂记1——typedef、static_cast、const_cast、遍历二维数组、聚合类

    1.typedef typedef一般是对某种类型的类型别名(不是变量别名) typedef double db;void mixtypename() {db d=1.2;cout<<d& ...

  7. 【C 语言】二级指针作为输入 ( 二维数组 | 二维数组遍历 | 二维数组排序 )

    文章目录 一.二维数组 1.二维数组声明及初始化 2.二维数组遍历 3.二维数组排序 二.完整代码示例 一.二维数组 前几篇博客中 , 介绍的是指针数组 ; 指针数组 的 结构特征 是 , 数组中的每 ...

  8. FineReport连接多维数据库示例及操作

    1. 描述 FineReport连接多维数据库,首先要通过数据连接将多维数据库与FineReport连接起来,然后在数据连接的基础上新建多维数据库XMLA数据集,用于模板设计. 2.XMLA数据连接 ...

  9. php多维数组遍历创建表格,php实现遍历多维数组的方法_PHP

    本文实例讲述了php实现遍历多维数组的方法.分享给大家供大家参考,具体如下: $a=array('fruits'=>array('a'=>'orange','b'=>'grape', ...

最新文章

  1. socket编程:I/O模型
  2. 技术人员突围就业寒冬的最优途径 | 拿不到AI核心岗位Offer全额退款
  3. 解决hibernate对Sql Server分页慢的问题
  4. python 常见内置函数setattr、getattr、delattr、setitem、getitem、delitem
  5. ExtJs Ext.TaskMgr定时刷新数据源
  6. SQL注入(SQL Injection)
  7. jQuery中的.bind()、.live()和.delegate()之间区别分析,学习jquery
  8. Python案例:输出公元后到目前为止全部回文日期
  9. vue在开发环境中配置本地hosts修改域名
  10. odoo stock库存模块
  11. cdrx8如何批量导出jpg_cdr怎么保存jpg格式
  12. 打印机服务器属性纸张自动改,“打印机设置自定义纸张”的解决方案
  13. [TJOI2019]唱、跳、rap和篮球
  14. 高德地图有用的API
  15. 滴水逆向三期笔记与作业——02C语言——02数据类型
  16. 后缀表达式的求值(c语言)
  17. [WPS]一次性解决论文插图的题注与章节号对不上问题
  18. error setting certificate verify locations: CAfile: F:/gitt/Git/mingw64/ssl/certs/ca-bundle.crt
  19. 零基础深度学习对金县房价预测
  20. MCU与MPU的区别

热门文章

  1. 构建最小JDK Docker镜像 或者直接使用镜像:frolvlad/alpine-oraclejre8:slim
  2. 程序员 30 岁前,该如何规划自己的职业发展?
  3. EFCore 迁移
  4. exit、_exit、abort、return的区别
  5. python 遍历文件夹
  6. C#:foreach语句,yield语句
  7. jquery插件:图片截取工具jquery.imagecropper.js
  8. 直接通过ADO操作Access数据库(修改版)
  9. ES6新特性_ES6扩展运算符的应用---JavaScript_ECMAScript_ES6-ES11新特性工作笔记014
  10. 基于Spring Security的认证授权_自定义登录页面_Spring Security OAuth2.0认证授权---springcloud工作笔记127