我正在编写数据库导入功能。我的语言是php。我的数据是JSON格式。
我的代码如下:
public function import($data = '') {
if (!isset($data)) {
return array(
'error' => "Error: no data"
);
}
$data_arr = json_decode($data, true);
if (is_array($data_arr) && sizeof($data_arr)) {
// Truncate DB table
$sql = 'TRUNCATE `ms_data`';
$this->db->query($sql)->execute();
// Import data
$sql = 'INSERT INTO `ms_data` (
`id`,
`name`,
`parent`,
`ordering`
) VALUES (
:id,
:name,
:parent,
:ordering
)';
foreach($data_arr as $d) {
$this->db->query($sql)
->bind(":id", $d['id'])
->bind(":name", trim($d['name']))
->bind(":ordering", $d['ordering'])
->execute();
}
return array(
'status' => 1,
'message' => 'Data has been imported'
);
} else {
return array(
'error' => "Input is not array"
);
}
}
这是有效的代码,但是:也许你知道我现在不知道的任何代码问题或任何改进建议?
谢谢!
答案 0 :(得分:2)
我看到一个问题:
如果使用此功能加载大量信息,则需要很长时间才能结束。
您可以使用单个查询加载所有数据,代码如下:
<?php
public function import($data = '') {
if (!isset($data)) {
return array(
'error' => "Error: no data"
);
}
$data_arr = json_decode($data, true);
if (is_array($data_arr) && sizeof($data_arr)) {
// Truncate DB table
$sql = 'TRUNCATE `ms_data`';
$this->db->query($sql)->execute();
$itemCount = count($data_arr);
// Import data
$sql = 'INSERT INTO `ms_data` (
`id`,
`name`,
`parent`,
`ordering`
) VALUES ';
for($i=1; $i <= $itemCount; $i++)
{
// Last item should not put comma after values.
if ($i == $itemCount)
{
$sql = $sql . "(?,?,?,?)"
}
else
{
$sql = $sql . "(?,?,?,?),"
}
}
$stmt = $this->db->prepare($sql);
$i = 1;
foreach($data_arr as $d) {
$stmt->bindParam($i++, $d['id'])
->bindParam($i++, trim($d['name']))
->bindParam($i++, $d['ordering']);
}
$stmt->execute();
return array(
'status' => 1,
'message' => 'Data has been imported'
);
} else {
return array(
'error' => "Input is not array"
);
}
}
?>
使用这种方式,您将在一个查询中插入所有行,这会大大减少执行时间,并且将是atomic operation。
答案 1 :(得分:0)
如果您有大量数据,则应执行以下操作:
1)创建一个用于加载数据的新表:CREATE TABLE new_data LIKE ms_data
2)按照您认为合适的方式填充数据:即INSERT INTO new_data VALUES (?,?,?,?)
3)用新表替换旧表:RENAME ms_data TO old_ms_data, new_data TO ms_data
。此操作是原子操作,因此对其他用户应该是不可见的。
4)清理,移除旧桌子:DROP TABLE old_ms_data
CREATE TABLE
,DROP TABLE
和RENAME TABLE
都会导致隐式提交,因此您无法将此作为单个事务执行,但由于RENAME TABLE
替换了数据在&#39; ms_data&#39;这仍然是原子的。
请注意,如果您对临时表使用静态名称(例如&#39; new_data&#39;),则无法同时执行两个加载过程。