php一次性大量數據入庫解決方法
當有業務需求需要一次性循環n條數據,插入或更新數據庫時,如果單純的循環,插入/更新,會消耗太多的數據庫資源
一下是一種簡單的解決方案
數據庫的insert 是可以批量更新的,當有大量數據循環insert時,可以將數據先保留不執行插入命令,到最後一條時一次性插入,例如tp的addAll()方法;
數據庫的update 如果使用case when 的話,也是可以批量更新的,本人在百度上找到了一個基於tp的saveAll()方法,用於更新數據
本文主要講關於批量insert;
例:
生成一個訂單
正常情況的語句為:
INSERT INTO order (`goods_id`,`num`,`price`) VALUES (1,1,
‘10.00‘
);
//封裝成函數
function
add_order(
$goods_id
,
$num
,
$price
){
$db
->query(
"INSERT INTO order (`goods_id`,`num`,`price`) VALUES ($goods_id,$num,$price)"
);
}
假設有一個用戶,一次性將購物車的1000個商品結算成訂單,生成1000個訂單時;
for
(
$i
=0;
$i
<1000;
$i
++){
$db
->query(
"INSERT INTO order (`goods_id`,`num`,`price`) VALUES ($goods_id,$num,$price)"
);
}
//這樣的話會導致服務器資源占用過大,網站卡死
//所以,我們可以
$sql
=
"INSERT INTO order (`goods_id`,`num`,`price`) VALUES "
;
for
(
$i
=0;
$i
<1000;
$i
++){
if
(
$i
==0){
$sql
.=
"($goods_id,$num,$price)"
;
}
else
{
$sql
.=
",($goods_id,$num,$price)"
;
}
}
$db
->query(
$sql
);
大概意思就是這樣了,批量更新實現比較麻煩一點,就不發了,以下是批量更新的sql執行語句
UPDATE
tiyan.dm_user_cupboard
SET
`res_id` =
CASE
`id`
WHEN
1041
THEN
‘1‘
WHEN
1058
THEN
‘1‘
WHEN
1055
THEN
‘1‘
END
,`food_code` =
CASE
`id`
WHEN
1041
THEN
‘68‘
WHEN
1058
THEN
‘47‘
WHEN
1055
THEN
‘49‘
END
,`food_name` =
CASE
`id`
WHEN
1041
THEN
‘紅棗‘
WHEN
1058
THEN
‘蓮藕‘
WHEN
1055
THEN
‘洋蔥‘
END
,`num` =
CASE
`id`
WHEN
1041
THEN
‘2‘
WHEN
1058
THEN
‘3‘
WHEN
1055
THEN
‘2‘
END
,`
level
` =
CASE
`id`
WHEN
1041
THEN
‘2‘
WHEN
1058
THEN
‘2‘
WHEN
1055
THEN
‘2‘
END
,`update_time` =
CASE
`id`
WHEN
1041
THEN
‘2017-12-09 21:40:06‘
WHEN
1058
THEN
‘2017-12-09 21:40:06‘
WHEN
1055
THEN
‘2017-12-09 21:40:06‘
END
WHERE
id
IN
( 1041,1058,1055 )
UPDATE tiyan.dm_user_cupboard SET `res_id` = CASE `id` WHEN 1041 THEN ‘1‘ WHEN 1058 THEN ‘1‘ WHEN 1055 THEN ‘1‘ END,`food_code` = CASE `id` WHEN 1041 THEN ‘68‘ WHEN 1058 THEN ‘47‘ WHEN 1055 THEN ‘49‘ END,`food_name` = CASE `id` WHEN 1041 THEN ‘紅棗‘ WHEN 1058 THEN ‘蓮藕‘ WHEN 1055 THEN ‘洋蔥‘ END,`num` = CASE `id` WHEN 1041 THEN ‘2‘ WHEN 1058 THEN ‘3‘ WHEN 1055 THEN ‘2‘ END,`level` = CASE `id` WHEN 1041 THEN ‘2‘ WHEN 1058 THEN ‘2‘ WHEN 1055 THEN ‘2‘ END,`update_time` = CASE `id` WHEN 1041 THEN ‘2017-12-09 21:40:06‘ WHEN 1058 THEN ‘2017-12-09 21:40:06‘ WHEN 1055 THEN ‘2017-12-09 21:40:06‘ END WHERE id IN ( 1041,1058,1055 )
附帶基於tp的saveAll()
//批量更新
public
function
saveAll(
$datas
,
$model
){
(
$model
||
$model
=
$this
->tableName);
$model
=
empty
(
$model
)?
$this
->name:
$model
;
$sql
=
‘‘
;
//Sql
$lists
= [];
//記錄集$lists
$pk
=
$this
->getPk();
//獲取主鍵
foreach
(
$datas
as
$data
) {
foreach
(
$data
as
$key
=>
$value
) {
if
(
$pk
===
$key
){
$ids
[]=
$value
;
}
else
{
$lists
[
$key
].= sprintf(
"WHEN %u THEN ‘%s‘ "
,
$data
[
$pk
],
$value
);
}
}
}
foreach
(
$lists
as
$key
=>
$value
) {
$sql
.= sprintf(
"`%s` = CASE `%s` %s END,"
,
$key
,
$pk
,
$value
);
}
$sql
= sprintf(
‘UPDATE __%s__ SET %s WHERE %s IN ( %s )‘
,
strtoupper
(
$model
),rtrim(
$sql
,
‘,‘
),
$pk
,implode(
‘,‘
,
$ids
));
return
M()->execute(
$sql
);
}
php一次性大量數據入庫解決方法