我需要一些帮助来循环遍历表并将行转换为新表中的单行。
表A包含100k +行。我想通过将值添加到json数组中来缩小表B中的内容。
表A具有以下结构:
+---------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| result_id | int(11) | NO | | 0 | |
| question_id | int(11) | NO | | 0 | |
| question_type | tinyint(4) | NO | | 0 | |
| answer | tinytext | NO | | NULL | |
| user_answer | tinytext | NO | | NULL | |
| exam_id | int(11) | NO | | NULL | |
+---------------+------------+------+-----+---------+----------------+
表B具有以下结构:
+------------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| exam_id | int(11) | NO | | NULL | |
| score | int(11) | NO | | NULL | |
| exam_data | text | NO | | NULL | |
| created_at | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| updated_at | timestamp | YES | | NULL | |
| deleted_at | timestamp | YES | | NULL | |
+------------+-----------+------+-----+-------------------+-----------------------------+
实际上,我想循环遍历表A中的所有行,并将具有相同result_id
的行添加到数组中。我想接着这个数组并在表B中插入一个新行。
这是我迄今为止所拥有的,但它无法正常运作。
$array = array();
$id = null;
TableA::chunk(100, function($answers)
{
foreach($answers as $old)
{
$id = $old->result_id;
if($id == $old->result_id)
{
$array[] = array("type" => $old->question_type, "answer" => $old->user_answer);
}
}
$new = new TableB;
$new->exam_id = $id;
$new->exam_data = json_encode($array);
$new->save();
});
我想利用Laravel chunk函数来避免SQL服务器超时。
有人能指出我正确的方向吗?
答案 0 :(得分:1)
我讨厌ORM采取与简单CRUD操作不同的操作。所以我将用简单的SQL /伪代码描述一个想法。
此外,为了节省内存,您可以在循环外部创建对象TableB,然后在循环中创建对象TableB以更改所需的字段。通过这种方式,您可以节省每次迭代创建新对象所需的内存和时间。
P.S。 为了更有效的方式,我会使用纯SQL查询。此外,最好动态创建查询,以便能够分批向db插入数据,而不是为每行执行INSERT。
我的意思是,首先构建包含多个插入的查询,然后通过只运行一个查询来插入它:
INSERT INTO Table ( Column1, Column2 ) VALUES
( Value1, Value2 ), ( Value1, Value2 )
答案 1 :(得分:1)
我建议做一个SELECT
,循环结果并使用result_id
创建数组的第一个维度。然后使用question_id
创建数组的第二个维度。
$aJsonResults = array();
foreach($aDatabaseResults as $key => $value){
$aJsonResults[$value['result_id']][$value['question_id']] = $value['answer'];
}
然后循环遍历第一级$aJsonResults
和json_encode
值。
$aJsonedResults = array()
foreach($aJsonResults as $key => $value){
$aJsonedResults[$key] = json_encode($value);
}
然后创建你的插入@ alexander-ravikovich的建议。