我试图在keyword
表格中插入关键字,并通过articles
表格将其映射到articleKeywordIndex
,但是已经卡在了车辙中,并且可能会在'出去。这是我的设置:
articles
-------------
articleID INT AUTO PRI
articleKeywordIndex
-------------
articleID INT UNIQUE
keywordID INT UNIQUE
keywords
-------------
keywordID INT PRI
keyword VARCHAR UNIQUE
我 使用INSERT INTO keywords (a) VALUES (:a) ON DUPLICATE KEY UPDATE a = a
但是我注意到自动增量奇怪地被更新并且让我感到困惑,因为我认为这是不会发生的方法。无论如何,我还需要抓住keywordID
是否存在,放入调音台,所以我去了一个try / catch解决方案,如果INSERT由于一个唯一的条目而失败,那么会选择要在另一个表中使用的keywordID。
现在发生了什么,如果关键字尚未存在,并且该表中已有4个关键字(1,2,3,4),则关键字表中的keywordID列会增加4 ,插入时将其设为8。如果这种情况一直发生并且我有很多关键字,那么关键字ID列的ID将是huuuuge!如果关键字DOES存在,则没有任何改变并且完美地运行。我想象它与循环循环4次有关,但我看不出问题。
以下是代码:
$tagsArray = explode(',', strtolower($tags));
for ($x = 0; $x < count($tagsArray); $x++) {
$keyword = trim($tagsArray[$x]);
try {
$SQL = "INSERT INTO keywords (keyword) VALUES (:keyword);";
$STH = $DBH -> prepare($SQL);
$STH -> bindParam(':keyword', $keyword);
$STH -> execute();
$keywordID = $DBH -> lastInsertId();
} catch (Exception $e) {
$SQL = "SELECT keywordID FROM keywords WHERE keyword = :keyword;";
$STH = $DBH -> prepare($SQL);
$STH -> bindParam(':keyword', $keyword);
$STH -> execute();
$keywordID = $STH -> fetchColumn();
}
$SQL = "INSERT INTO articleKeywordIndex (articleID, keywordID) VALUES (:saveToID, :keywordID)
ON DUPLICATE KEY UPDATE articleID = articleID, keywordID = keywordID;";
$STH = $DBH -> prepare($SQL);
$STH -> bindParam(':saveToID', $saveToID);
$STH -> bindParam(':keywordID', $keywordID);
$STH -> execute();
}
我认为这不是很多,因为我只有~3000-5000个关键词,但它仍然很烦人,想知道出了什么问题。
解决方案
事实证明,使用INSERT ON DUPLICATE KEY UPDATE
时,使用InnoDB引擎会导致奇数增量更改。这实际上是几年前报告的一个错误并且发布了补丁,但后来它被证明是一个特意设计的功能,my.cnf中的设置禁用它。这是一个奇怪的故事,需要一段时间来了解它。无论如何,在my.cnf
,我改变了这个:
innodb_autoinc_lock_mode=0
所有这些都恢复正常,我的脚本按照我的想法,当我第一次写它时,在其他五次尝试之前!我使用InnoDB进行交易,因此我还没有准备好切换到MyISAM。
答案 0 :(得分:1)
您的代码看起来不错?我可能会尝试以下操作,看看是否有效。
首先,使用SELECT @@auto_increment_increment;
检查auto_increment_increment。也许出于某种原因它被设置为4?
如果您手动使用mySQL添加记录怎么办?它还能上升到4吗?如果是,则可能与您的代码无关。
你说它可能与循环循环4次有关。您是否尝试使用化妆阵列进行循环,例如... 6个元素?它会上升到6?
我还要检查并确保没有任何隐藏的程序或触发器在幕后工作。
EDIT1:准备离开循环。我认为既然有或没有on update
你似乎仍然有奇数增量值问题,也可以再次使用...on update
$tagsArray = explode(',', strtolower($tags));
$SQL = "INSERT INTO keywords (keywordID, keyword) VALUES (NULL, :keyword)
ON DUPLICATE KEY UPDATE keywordID=LAST_INSERT_ID(keywordID), keyword = keyword;
INSERT INTO articleKeywordIndex (articleID, keywordID) VALUES (:saveToID, LAST_INSERT_ID())
ON DUPLICATE KEY UPDATE articleID = articleID, keywordID = keywordID;";
$STH = $DBH -> prepare($SQL);
$STH -> bindParam(':saveToID', $saveToID); //<--I actually haven't tried this, if it doesn't work move it back into loop.
for ($x = 0; $x < count($tagsArray); $x++) {
$STH -> bindParam(':keyword', trim($tagsArray[$x]));
$STH -> execute();
}
答案 1 :(得分:0)
事实证明,当使用INSERT ON DUPLICATE KEY UPDATE时,使用InnoDB引擎会导致奇数增量更改。这实际上是几年前报告的一个错误并且发布了补丁,但后来它被证明是一个特意设计的功能,my.cnf中的设置禁用它。这是一个奇怪的故事,需要一段时间来了解它。无论如何,在my.cnf
,我改变了这个:
innodb_autoinc_lock_mode = 0
一切都恢复正常。我使用InnoDB进行交易,因此我还没有准备好切换到MyISAM。