我有一个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>
在这种情况下,最佳做法是什么?是否有其他更好的方法可以达到预期的效果?
答案 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)');