如何优化将 mysql 关系数据导出为 php 中的 json

How to optimize exporting mysql relational data as json in php

我现在正在开发模块,将数据生成为以下结构,从 mysql 到 json。

 {"employee":
   [
      {"id":1,
       "name":"jhon doe",
       "register_date":"2011-05-11",
       "education":
             [ 
                {"degree":"B.A","description":"History"},
                {"degree":"M.A","description":"History"}
             ]
       },
       {"id":2,
       "name":"Smith",
       "register_date":"2011-06-11",
       "education":
             [ 
                {"degree":"B.E","description":"Mechnical"},
                {"degree":"M.E","description":"Mechnical"}
             ]
       }
   ]
 }

为此,首先,我按以下 register_date 范围检索员工数据。

 $result=mysql_query("SELECT * FROM employee WHERE register_date>'2011-04-31' AND register_date<'2011-07-01'");

然后我迭代结果中的每一行并从教育 table 中检索教育信息,如下所示:

 while($row = mysql_fetch_assoc($result)){
   $id=$row["id"];
   $education=mysql_query("SELECT degree,description from education where emp_id=$id");
   // assigning education array as educaiton field in $row
   // write json_encode($row) to output buffer
} 

这个项目的数据结构不是我设计的,我知道在 education 中将 employee'id 设置为外键不是一个好主意 table,相反,应该将 education id 设置为 employee 中的外键 table。我的问题是(通过使用此数据结构)为每一行员工检索教育列表是一个巨大的性能问题,因为一个月可能有大约 500000 条员工记录,对于这个数量,mysql select每个员工的教育数据检索查询必须处理 500000 次。我应该如何优化。

1.Should我改变数据结构?
2. 我是否应该创建直接从数据库生成 json 字符串的 mysql 存储过程?
3. 我应该对员工 table 中的教育数据进行反规范化吗?
哪种方法最有效或有什么建议?

请帮帮我。

您可以在 php 循环中获取员工并分配他们之后查询教育数据。

$result = mysql_query("select * from employee where register_date > '2011-04-31' and register_date < '2011-07-01'");

$employees = [];

while ($row = mysql_fetch_assoc($result)) {
    $id = $row['id'];
    $employees[$id] = $row;
}

$ids = join(', ', array_keys($employees));

$result = mysql_query(sprintf('select degree, description, employee.id as employee_id from education left join employee on emp_id = employee.id where employee.id in (%s)', $ids));

while ($row = mysql_fetch_assoc($result)) {
    $id = $row['employee_id'];
    unset($row['employee_id']);

    if (!isset($employees[$id]['education'])) {
        $employees[$id]['education'] = [];
    }

    $employees[$id]['education'][] = $row;
}

正如评论中所指出的,您可能只使用某种 JOIN

除此之外,我想向您介绍以下快速且 肮脏 的解决方案。这可能会使用 大量 ram

$arr_education = array();
$res_education = mysql_query("SELECT emp_id, degree, description FROM education");

while($row_education = mysql_fetch_assoc($res_education)) {
    $arr_education[$row_education["emp_id"]] = array("degree"=>$row_education["degree"], "description" => $row_education["description"]);
}

$result=mysql_query("SELECT * FROM employee WHERE register_date>'2011-04-31' AND register_date<'2011-07-01'");

while($row=mysql_fetch_assoc($result)) {
    //$arr_education[$row["id"]] is an array containing the education-entries for the employee
    $tmp = $row;
    $tmp["education"] = $arr_education[$row["id"]];
    echo json_encode($tmp);
}

针对您的具体问题:

  1. 如果 emp -> education 是一对一的关系,你应该改变数据结构。

  2. 不要那样做

  3. 不要那样做

考虑改用 PDO! http://php.net/manual/en/book.pdo.php 在这种特定情况下它不会帮助你,但你应该永远不会使用mysql_*函数。

更好的是你可以使用 SP 来处理数据然后到 return JSON 字符串。 让DB系统处理和迭代。我觉得和现在的实现相比会有很大的提升。