如何优化将 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);
}
针对您的具体问题:
如果 emp -> education 是一对一的关系,你应该改变数据结构。
不要那样做
不要那样做
考虑改用 PDO! http://php.net/manual/en/book.pdo.php
在这种特定情况下它不会帮助你,但你应该永远不会使用mysql_*
函数。
更好的是你可以使用 SP 来处理数据然后到 return JSON 字符串。
让DB系统处理和迭代。我觉得和现在的实现相比会有很大的提升。
我现在正在开发模块,将数据生成为以下结构,从 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);
}
针对您的具体问题:
如果 emp -> education 是一对一的关系,你应该改变数据结构。
不要那样做
不要那样做
考虑改用 PDO! http://php.net/manual/en/book.pdo.php
在这种特定情况下它不会帮助你,但你应该永远不会使用mysql_*
函数。
更好的是你可以使用 SP 来处理数据然后到 return JSON 字符串。 让DB系统处理和迭代。我觉得和现在的实现相比会有很大的提升。