INSERT ... ON DUPLICATE KEY UPDATE与客户端流量控制:优点和缺点

时间:2012-11-26 13:34:15

标签: mysql codeigniter activerecord

我有一个SQL表,我必须根据主键的存在插入或更新数据。上下文是在MySQL上运行的基于CodeIgniter的PHP Web应用程序。我发现INSERT...ON DUPLICATE KEY UPDATE语句完全符合我的需要,但在此之前,代码基于CI的Active Record实现,看起来像这样:

$res = $this->db->get_where('table', array('id' => $this->_id));
if(count($res->result_array()) > 0) { // update if present
    $this->db->where(array('id' => $this->_id));
    $this->db->update('table', $hash);
    return 2;
} else { // new entry if not present
    $personal_data['id'] = $this->_id;
    $this->db->insert('table', $hash);
    return 1;
}

这个项目中的其他开发人员要求我保持简单,优先考虑Active Record代码而不是直接的SQL和准备好的查询,经过一段时间的思考,我不确定在这种情况下最适合的情况是什么两种情况都有利弊。

例如,从流量控制的角度来看,Active Record解决方案非常简单,但是性能有很大的缺点,潜在的并发问题存在更大的缺点(如果第一个查询所声明的条件在执行之前发生了变化第二个查询,结果是不可预测的。)

另一方面,INSERT...ON DUPLICATE KEY UPDATE工作正常并且避免了并发问题,但仅限MySQL,可能导致可移植性问题,而且无法使用CI的Active Record构建,我需要准备好的查询。 / p>

在这种情况下,最佳做法是什么?是否有其他更好的方法可以达到预期的效果?

2 个答案:

答案 0 :(得分:1)

最佳做法是让数据库处理此类约束,原因很简单,否则您需要信任应用程序的行为。

如果将其保留在数据库中,则可以允许任何/多个应用程序操作数据,而不必担心它们会破坏数据库架构。

答案 1 :(得分:0)

还有另一种解决方案可以保持CI活动记录。

$query_string = $this->db->insert_string('table', array('id' => $this->_id, 'hash' => $hash));

$this->db->query($query_string.' ON DUPLICATE KEY UPDATE hash=VALUES(hash)');