Frage

Ich frage mich, ob es der Serverzeit wert ist, wenn eine Aufzeichnung der Aktualisierung der bestehenden Datensatz, Schleife durch die Felder Überprüfung für Änderungen und nur setzen die geänderten Felder in der Update-Abfrage abzurufen? (Ich verwende MySQL & PHP).

Der Hauptgrund dafür, dies zu tun ist, um die Größe der Update-Abfrage für Änderungsprotokoll Zwecke zu reduzieren. Normalerweise kann die Abfrage 15 Felder, aber nur zwei Felder tatsächlich geändert wird. Diese Abfrage kann dann auch für die Protokollierung verwendet werden, da es nur die geänderten Felder enthalten wird und daher leichter zu analysieren.

Meine Sorge ist, die Zeit, die es den vorhandenen Datensatz abzurufen nimmt.

Oder gibt es eine Möglichkeit, von MySQL abrufen, die sie aktualisierten Felder?

War es hilfreich?

Lösung

Ich denke, es lohnt sich zu ändern -. Aber wahrscheinlich nicht wert, bevor Einsatz eine Auswahl tun

Ich aktualisiere nur die Felder, die sich geändert haben, ist es Teil der Operation meines DbEntity Klasse ist, die ein Active Record folgt. Es kostet etwas mehr, dies zu tun, weil ich die aktuellen Datensatz und Original-Aufzeichnungen -einfach Kopieren halten, wenn ein Datensatz geladen wird.

Die Gründe dafür sind der Kürze - nicht wirklich Leistung. Sie können auch für die gleichzeitige Änderung überprüfen, indem Sie eine where-Klausel auf den alten Wert der aktualisierten Felder hinzufügen und die entsprechenden Fehler werfen.

In der Schreib- / Aktualisierungsmethode:

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

In der Load-Methode

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

Andere Tipps

Auf der untersten Ebene, wenn ich Ihre Frage richtig zu lesen, Sie wollen im Allgemeinen nicht blind den gesamten Datensatz aktualisieren, falls ein anderer Benutzer hat bereits Teile dieses Datensatz aktualisiert, die Sie haben nicht wirklich verändert. Sie würden blind und unnötig ihre Updates zurück.

Ich glaube, Ihr aktueller Algorithmus zu schmutzig schreibt führen kann, wenn Sie die aktuellen einmal zur Aktualisierung lesen, gehen, erlauben Updates im Speicher gemacht wird, dann den Datensatz wieder zu lesen, damit Sie herausfinden, welche Felder haben Aktualisiert. Was passiert, wenn ein anderer Benutzer aktualisiert, dass Datensatz hinter Ihrem Rücken, was Ihren Algorithmus zu glauben, dass Sie derjenige waren, um das Feld zu aktualisieren? Aber in erster Linie, sollten Sie nicht zweimal jeden Datensatz zu lesen, um ein einzelnes Update durchführen.

Wenn Sie Ihre Daten häufig nicht in Konflikten zur Folge hat, können Sie von der Lektüre über die optimistische Sperren profitieren, auch wenn Sie nicht zu ihrer Umsetzung wählen.

Wir haben eine Methode, die hier umgesetzt, wobei Sie einen Update-Zeitstempel oder eine inkrementelle Update-Nummer Spalte zu Ihrer Tabelle hinzuzufügen. Dann in der Sandbox / Speicher können Sie verfolgen, welche Felder Sie geändert haben (OldValue / newvalue), und Sie können Ihre Update SQL für diesen Datensatz für diese Felder frei Ausgabe von „UPDATE ... WHERE UPDATENUM = the-original-Nummer "(oder WHERE UPDATETS = den originalen-Zeitstempel), um sicherzustellen, dass das Update SQL erhöht auch die UPDATENUM oder UPDATETS, falls erforderlich. Wenn die Datensätze betroffenen durch dieses Update SQL 0 wissen Sie, dass jemand anderes bereits diesen Rekord im Hintergrund geändert hat, und Sie haben jetzt einen Konflikt. Aber wenigstens hast du nicht jemand andere Änderungen überschreibt, und Sie können dann die neuen Daten wieder gelesen oder haben Ihre Benutzer den Konflikt lösen.

Der langsamste Punkt in Ihrer Anwendung wird immer auf Ihre Datenbank zugreifen sein, wenn Sie also, dass bis beschleunigen können, es ist eine gute Idee. Das sagte, es hängt wirklich davon ab, wie groß Ihre Datenbank, und Aufzeichnungen sind, und wie groß sie sind wahrscheinlich zu wachsen, als ob es die Mühe lohnt sich programmatisch zu überprüfen, ob die Elemente aktualisiert haben. Wenn Ihre Datenbank klein ist und der Zugang ist schon ziemlich schnell, kann es nicht die Zeit wert sein. Aber wenn die Geschwindigkeit verbessert werden kann, und es gibt Ihnen einen zusätzlichen Nutzen für die Protokollierung, dann gehen sie.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top