您是否只更新已更改的字段或所有字段?

Dar*_*ein 10 mysql changelog sql-update

我想知道更新记录以检索现有记录是否值得服务器时间,循环检查更改的字段并仅将更改的字段放入更新查询中?(我使用的是MySQL和PHP.)

执行此操作的主要原因是为了更改日志目的而减小更新查询的大小.通常,查询可能有15个字段,但实际上只有2个字段正在更改.此查询也可以用于日志记录,因为它只包含更改的字段,因此更容易解析.

我担心的是检索现有记录所需的时间.

或者有没有办法从MySQL检索它更新的哪些字段?

Ric*_*son 3

我认为值得改变 - 但可能不值得在插入之前进行选择。

我只更新已更改的字段,这是我的 DbEntity 类操作的一部分,该类遵循 activerecord 模式。执行此操作几乎不需要额外费用,因为我保存当前记录和原始记录 - 只要加载记录即可复制。

原因很简单——并不是真正的性能。您还可以通过在更新字段的旧值上添加 where 子句来检查并发修改,并抛出相应的错误。

在写入/更新方法中:

$s1 = "";

foreach ($this->record as $key => $value)
{
    // only update fields that have been changed
    if ($value != $this->orig_record[$key])
    {
        $s1 .= $comma."`$key`='".mysql_real_escape_string($value)."'";
        $comma = ", ";
    }
}

$query = "UPDATE ".$this->table." SET $s1 where {$this->id_field}='".$this->get_keyfield()."'";
$query .= $this->extra_sql_update;
mysql_query($query);

$ar = mysql_affected_rows();
//
// the number of affected rows is actually those changed by the update operation, which will 
// either be zero, or 1. If the query affects more than one row then we have a problem.
if ($ar < 0 || $ar > 1)
{
    cbf_error("cbf_dbentity: {$this->table} :: only one row (not $ar) must be affected by an insert operation. $query",
      E_USER_ERROR);
}
else
{
    $new_id = $this->get_keyfield();

    GlobalEventBus::notify_all(new AuditLogSQL($this->table, "update", $query));

}

$this->orig_record = Array();

foreach ($this->record as $key => $value)
    $this->orig_record[$key] = $value;


//
// sanity check - ensure that what we have just written is actually there.

$this->load($new_id);

foreach ($this->orig_record as $key => $value)
    if (trim($this->record[$key]) != trim($value) 
        && (!$this->record[$key] == "0" && $value=""))
        cbf_error("cbf_dbentity: {$this->table} :: record differs during write after reload: field $key was \"$value\", after write it is now \"".
              $this->record[$key]."\"",E_USER_ERROR);
Run Code Online (Sandbox Code Playgroud)

在加载方法中

$this->orig_record = Array();
foreach ($this->record as $key => $value)
    $this->orig_record[$key] = $value;
Run Code Online (Sandbox Code Playgroud)