문제

기존 레코드를 검색하기 위해 레코드를 업데이트 할 때 서버 시간의 가치가 있는지 궁금합니다. 기존 레코드를 검색하고 필드를 통과하여 변경 사항을 확인하고 변경된 필드를 업데이트 쿼리에만 넣습니다. (저는 MySQL & Php를 사용하고 있습니다.)

이를 수행하는 주된 이유는 변경 로그 목적으로 업데이트 쿼리의 크기를 줄이기 때문입니다. 일반적으로 쿼리에는 15 개의 필드가있을 수 있지만 실제로 2 개의 필드 만 변경됩니다. 그런 다음이 쿼리는 변경된 필드 만 포함하므로 로깅에 사용할 수 있으므로 구문 분석하기가 더 쉽습니다.

내 관심사는 기존 레코드를 검색하는 데 걸리는 시간입니다.

아니면 MySQL에서 어떤 필드를 업데이트했는지 검색하는 방법이 있습니까?

도움이 되었습니까?

해결책

변경할 가치가 있다고 생각하지만 삽입 전에 선택을 할 가치가 없을 것입니다.

변경된 필드 만 업데이트합니다. ActiveRecord 패턴을 따르는 DBENTITY 클래스의 작동의 일부입니다. 현재 레코드와 원본 레코드를 보유하고 있기 때문에이를 수행하는 데 비용이 거의 들지 않습니다. 레코드가로드 될 때마다 간단하게 복사합니다.

이유는 간결합니다. 실제로 성능이 아닙니다. 또한 업데이트 된 필드의 이전 값에 대한 WHER 절을 추가하여 동의 수정을 확인하고 적절한 오류를 던질 수 있습니다.

쓰기/업데이트 방법에서 :

$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);

로드 방법에서

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

다른 팁

가장 기본적인 수준에서 질문을 올바르게 읽는 경우 일반적으로 다른 사용자가 실제로 변경하지 않은 해당 레코드의 일부를 업데이트 한 경우 일반적으로 전체 레코드를 맹목적으로 업데이트하고 싶지 않습니다. 당신은 맹목적이고 불필요하게 그들의 업데이트를 되돌릴 것입니다.

현재 알고리즘이 더러운 쓰기로 이어질 수 있다고 생각합니다. 업데이트를 위해 현재를 한 번 읽으려면 메모리에서 업데이트를 다시 작성한 다음 레코드를 다시 읽어 어떤 필드가 업데이트되었는지 확인할 수 있습니다. 다른 사용자가 등 뒤에 해당 레코드를 업데이트하여 알고리즘을 이끌면 어떻게됩니까? 그 분야를 업데이트 할 사람 이었습니까? 그러나 주로 단일 업데이트를 수행하기 위해 모든 레코드를 두 번 읽을 필요는 없습니다.

데이터가 종종 충돌을 일으키지 않는 경우, 구현을 선택하지 않더라도 낙관적 잠금에 대한 읽을 수 있습니다.

여기서는 하나의 방법을 구현하여 업데이트 타임 스탬프 또는 증분 업데이트 수 열을 테이블에 추가했습니다. 그런 다음 샌드 박스/메모리에서 수정 한 필드 (OldValue/NewValue)를 추적 할 수 있으며 해당 필드의 해당 레코드에 대한 업데이트 SQL을 자유롭게 발행 할 수 있습니다. "(또는 updatets = the-original-timestamp), 업데이트 SQL에도 업데이트 또는 업데이트가 적절하게 증가하는지 확인하십시오. 해당 업데이트에 영향을받는 레코드가 0이라면 다른 사람이 이미 백그라운드에서 해당 레코드를 수정했으며 이제 충돌이 있음을 알고 있습니다. 그러나 적어도 다른 사람의 변경 사항을 덮어 쓰지 않았으며 새 데이터를 다시 읽거나 사용자가 충돌을 해결하도록 할 수 있습니다.

응용 프로그램에서 가장 느린 지점은 항상 데이터베이스 액세스가 될 것이므로 속도를 높일 수 있다면 좋은 생각입니다. 그것은 실제로 데이터베이스가 얼마나 큰지, 레코드가 얼마나 큰지, 그리고 어떻게 성장할 가능성이 높습니다. 항목이 업데이트되었는지 프로그래밍 방식으로 노력할 가치가 있는지 여부에 대해서는 상품이 업데이트되었습니다. 데이터베이스가 작고 액세스가 이미 매우 빠르면 시간이 가치가 없을 수도 있습니다. 그러나 속도를 향상시킬 수 있고 로깅에 추가적인 이점을 제공한다면 이동하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top