编辑:我忘了提到我的脚本不应该输入如果新行中已存在具有相同列值的行,这就是我所说的"重复条目"尽管没有共同的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。
思想?
答案 0 :(得分:1)
事实上,你已经解决了这个问题,但出于某种原因已经中途停止了。
这种方法的问题在于运行时非常糟糕,我设法通过使用数据库事务大大减少了运行时间
我想知道为什么你也不包括选择进入交易。
思想?
只需添加您在第一个变体中运行的选择查询。这就是全部。
答案 1 :(得分:1)
嗯,我相信你不必使用脚本,查询将是enoguh:
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
(记录为here)。
答案 2 :(得分:0)
我还没有完全理解: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字会自动丢弃任何产生主要唯一密钥冲突的插入内容。
您也可以直接从选择查询中插入。这可以使这项工作更容易