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

时间:2015-01-09 04:23:25

标签: php mysql json

我现在正在开发模块,它将以下结构生成数据到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'");

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

 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
} 

这个项目的数据结构不是我的设计,我知道将员工的ID设置为教育表中的外键并不是一个好主意,而应该将教育ID设置为国外员工表中的密钥。我的问题是(通过使用这种数据结构)检索每一行员工的教育列表是一个巨大的性能问题,因为一个月可能有大约500000名员工记录,对于该数量,mysql选择查询必须处理500000次每位员工的教育数据检索。我应该如何优化。

1.我应该改变数据结构吗? 2.我应该创建直接从数据库生成json字符串的mysql存储过程吗? 3.我应该在员工表中对教育数据进行非规范化吗? 这是最有效的方法还是任何建议?

请帮帮我。

3 个答案:

答案 0 :(得分:1)

您可以在获取员工并在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;
}

答案 1 :(得分:0)

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

除此之外,我想向您介绍以下快速&amp; 解决方案。这可能会使用很多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 - &gt;教育是1比1的关系,你应该改变数据结构。

  2. 不要那样做

  3. 不要那样做

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

答案 2 :(得分:0)

更好的是,您可以使用SP来处理数据,然后返回JSON字符串。 让DB系统处理并迭代。我认为与目前的实施相比,它会有很大改善。