编辑:我忘了提到我的脚本不应该输入,如果一行已经存在于新的数据库中具有相同的列值,这就是我所指的"重复条目",尽管没有一个共同的PK。
这是我的困境,我正在使用MySQLi将数据从旧表迁移到具有不同设计的新表中,我希望我的程序能够多次运行而无需乘以以前的条目。我最初的方法是为每个插入的元素做一个验证查询:
//foreach elt of old table:
$a = $old_table['a'];
$b = $old_table['b'];
$query = $db->query("SELECT `id` FROM `old_table`
WHERE `a` = '$b'
AND `b` LIKE '$b'")->fetch_assoc();
if ($query == null) {
//insert a row into the new table
}
这种方法的问题是运行时非常可怕,我设法通过使用数据库事务来大大减少它:
$query = $db->prepare("INSERT INTO `new_table`
(`a`, `b`, `c`, `d`, `e`)
VALUES (?, ?, ?, ?, ?)");
$query->bind_param('isssi', $a, $b, $c, $d, $e);
$db->query("START TRANSACTION");
foreach ($old_table as $old_row) {
$a = $old_row['a'];
...
$e = $old_row['e'];
$query->execute();
}
$query->close();
$db->query("COMMIT");
这个方法的问题是,如果程序多次运行,它会产生多个条目。重要的是要注意,由于两个表有不同的设计,没有共同的主键,因此我认为我不能使用DUPLICATE Key。
想法吗?
事实上,你已经解决了这个问题,但由于某种原因中途停了下来。
这种方法的问题是运行时非常可怕,我设法通过使用数据库事务
大大减少了它。
我想知道你为什么不把select也包含到事务中。
想法吗?
只需添加用于在第一个变体中运行的select查询。就是这样。
好吧,我相信你不必须使用脚本,一个查询就足够了:
SELECT
/* your complex columns, from and joins go here */
LEFT JOIN `new_table` n ON n.a = old_table.a AND n.b LIKE old_table.b
WHERE
n.a IS NULL AND n.b IS NULL AND
/* your WHERE and LIMIT go here */
此方法利用LEFT JOIN
,如果在正确的表中没有匹配的行,则将所有列设置为NULL
(此处有文档说明)。
我还没有完全理解:there is no common KEY and therefore I can't do a DUPLICATE KEY.
,所以我不确定你会发现这有用,但你可以选择,如果你使用它…
也许你会发现更简单,如果你只是尝试INSERT IGNORE
:
INSERT IGNORE INTO new_table (a,b,c,d)
SELECT a,b,c,d FROM old_table
IGNORE word将自动丢弃任何产生主键或唯一键冲突的插入。
您也可以直接从选择查询中插入。