PHP-Batch-Update

不言
不言Original
2018-07-06 16:23:505851Durchsuche

Dieser Artikel stellt hauptsächlich das Batch-Update von PHP vor, das einen bestimmten Referenzwert hat. Jetzt kann ich es mit allen teilen, die es brauchen.

Die MySQL-Update-Anweisung ist sehr einfach Ein Feld wird normalerweise so geschrieben:

UPDATE mytable SET myfield = 'value' WHERE other_field = 'other_value';

Wenn Sie dasselbe Feld auf denselben Wert aktualisieren, ist MySQL auch sehr einfach, ändern Sie einfach wo:

UPDATE mytable SET myfield = 'value' WHERE other_field in ('other_values');

Hinweis Hier ist other_values ein Komma, getrennte Zeichenfolgen, wie zum Beispiel: 1,2,3

1 Konventionelle Lösung
Wenn Sie mehrere Daten auf unterschiedliche Werte aktualisieren, schreiben viele Leute möglicherweise so:

foreach ($display_order as $id => $ordinal) {
    $sql = "UPDATE categories SET display_order = $ordinal WHERE id = $id";
    mysql_query($sql);
}

Das heißt, die Aktualisierungsdatensätze werden einzeln durchlaufen.

Ein Datensatz update einmal, was eine schlechte Leistung aufweist und leicht zu Blockierungen führen kann.

2 Effiziente Lösung
Können Batch-Updates also mit einer SQL-Anweisung implementiert werden?

2.1 CASE WHEN
MySQL bietet keine direkte Methode zur Implementierung von Batch-Updates, kann aber mit ein paar Tricks erreicht werden.

UPDATE mytable SET
    myfield = CASE id
        WHEN 1 THEN 'value'
        WHEN 2 THEN 'value'
        WHEN 3 THEN 'value'
    END
WHERE id IN (1,2,3)

Hier verwenden wir den case when-Trick, um Batch-Updates zu erreichen.

Zum Beispiel:

UPDATE categories SET
    display_order = CASE id
        WHEN 1 THEN 3
        WHEN 2 THEN 4
        WHEN 3 THEN 5
    END
WHERE id IN (1,2,3)

Diese SQL bedeutet, das Feld display_order zu aktualisieren:

Wenn id=1, ist der Wert von display_order 3,
Wenn id =2, der Wert von display_order ist 4,
Wenn id=3, ist der Wert von display_order 5.
Das heißt, bedingte Anweisungen werden zusammen geschrieben.

Der Where-Teil hier hat keinen Einfluss auf die Ausführung des Codes, verbessert jedoch die Effizienz der SQL-Ausführung.

Stellen Sie sicher, dass die SQL-Anweisung nur die Anzahl der zu ändernden Zeilen ausführt. Es müssen nur 3 Datenzeilen aktualisiert werden, und die where-Klausel stellt sicher, dass nur 3 Datenzeilen ausgeführt werden.

3.2 Mehrere Werte aktualisieren
Wenn Sie mehrere Werte aktualisieren möchten, müssen Sie nur geringfügige Änderungen vornehmen:

UPDATE categories SET
    display_order = CASE id
        WHEN 1 THEN 3
        WHEN 2 THEN 4
        WHEN 3 THEN 5
    END,
    title = CASE id
        WHEN 1 THEN 'New Title 1'
        WHEN 2 THEN 'New Title 2'
        WHEN 3 THEN 'New Title 3'
    END
WHERE id IN (1,2,3)

An diesem Punkt haben Sie eine MySQL-Anweisung zum Aktualisieren mehrerer Datensätze abgeschlossen .

Aber um es im Geschäftsleben nutzen zu können, muss es mit serverseitiger Sprache kombiniert werden.

3.3 In PHP-Funktion kapseln
In PHP kapseln wir diese Funktion in eine Funktion und rufen sie später direkt auf.

Um die Benutzerfreundlichkeit zu verbessern, erwägen wir die Handhabung umfassenderer Szenarien.

Die folgenden Daten müssen aktualisiert werden. Wir müssen den Inhalt der Tabelle id basierend auf den Feldern parent_id und post aktualisieren.

Unter diesen ändert sich der Wert von id und der Wert von parent_id bleibt gleich.

$data = [
    ['id' => 1, 'parent_id' => 100, 'title' => 'A', 'sort' => 1],
    ['id' => 2, 'parent_id' => 100, 'title' => 'A', 'sort' => 3],
    ['id' => 3, 'parent_id' => 100, 'title' => 'A', 'sort' => 5],
    ['id' => 4, 'parent_id' => 100, 'title' => 'B', 'sort' => 7],
    ['id' => 5, 'parent_id' => 101, 'title' => 'A', 'sort' => 9],
];

Zum Beispiel möchten wir, dass die Datensätze mit parent_id 100 und title A sein sollen, um in Stapeln basierend auf verschiedenen IDs aktualisiert zu werden:

echo batchUpdate($data, 'id', ['parent_id' => 100, 'title' => 'A']);

Darunter auch PHP Der von batchUpdate() implementierte Code lautet wie folgt:

/**
 * 批量更新函数
 * @param $data array 待更新的数据,二维数组格式
 * @param array $params array 值相同的条件,键值对应的一维数组
 * @param string $field string 值不同的条件,默认为id
 * @return bool|string
 */
function batchUpdate($data, $field, $params = [])
{
   if (!is_array($data) || !$field || !is_array($params)) {
      return false;
   }

    $updates = parseUpdate($data, $field);
    $where = parseParams($params);

    // 获取所有键名为$field列的值,值两边加上单引号,保存在$fields数组中
    // array_column()函数需要PHP5.5.0+,如果小于这个版本,可以自己实现,
    // 参考地址:http://php.net/manual/zh/function.array-column.php#118831
    $fields = array_column($data, $field);
    $fields = implode(',', array_map(function($value) {
        return "'".$value."'";
    }, $fields));

    $sql = sprintf("UPDATE `%s` SET %s WHERE `%s` IN (%s) %s", 'post', $updates, $field, $fields, $where);

   return $sql;
}

/**
 * 将二维数组转换成CASE WHEN THEN的批量更新条件
 * @param $data array 二维数组
 * @param $field string 列名
 * @return string sql语句
 */
function parseUpdate($data, $field)
{
    $sql = '';
    $keys = array_keys(current($data));
    foreach ($keys as $column) {

        $sql .= sprintf("`%s` = CASE `%s` \n", $column, $field);
        foreach ($data as $line) {
            $sql .= sprintf("WHEN '%s' THEN '%s' \n", $line[$field], $line[$column]);
        }
        $sql .= "END,";
    }

    return rtrim($sql, ',');
}

/**
 * 解析where条件
 * @param $params
 * @return array|string
 */
function parseParams($params)
{
   $where = [];
   foreach ($params as $key => $value) {
      $where[] = sprintf("`%s` = '%s'", $key, $value);
   }
   
   return $where ? ' AND ' . implode(' AND ', $where) : '';
}

Rufen Sie eine solche Batch-Update-SQL-Anweisung ab:

UPDATE `post` SET `id` = CASE `id` 
WHEN '1' THEN '1' 
WHEN '2' THEN '2' 
WHEN '3' THEN '3' 
WHEN '4' THEN '4' 
WHEN '5' THEN '5' 
END,`parent_id` = CASE `id` 
WHEN '1' THEN '100' 
WHEN '2' THEN '100' 
WHEN '3' THEN '100' 
WHEN '4' THEN '100' 
WHEN '5' THEN '101' 
END,`title` = CASE `id` 
WHEN '1' THEN 'A' 
WHEN '2' THEN 'A' 
WHEN '3' THEN 'A' 
WHEN '4' THEN 'B' 
WHEN '5' THEN 'A' 
END,`sort` = CASE `id` 
WHEN '1' THEN '1' 
WHEN '2' THEN '3' 
WHEN '3' THEN '5' 
WHEN '4' THEN '7' 
WHEN '5' THEN '9' 
END WHERE `id` IN ('1','2','3','4','5')  AND `parent_id` = '100' AND `title` = 'A'

Die generierte SQL listet alle Situationen auf.

Aufgrund der WHERE-Bedingungen werden jedoch nur die Datensätze mit den IDs 1, 2 und 3 aktualisiert.

Wenn Sie nur eine bestimmte Spalte aktualisieren müssen und andere Bedingungen nicht eingeschränkt sind, können die eingehenden $data einfacher sein:

$data = [
    ['id' => 1, 'sort' => 1],
    ['id' => 2, 'sort' => 3],
    ['id' => 3, 'sort' => 5],
];
echo batchUpdate($data, 'id');

Wenn das Datenformat übergeben wird, können Sie es ändern id von 1 Für Datensätze von ~3 ändern Sie sort in 1, 3 bzw. 5.

Rufen Sie die SQL-Anweisung ab:

UPDATE `post` SET `id` = CASE `id` 
WHEN '1' THEN '1' 
WHEN '2' THEN '2' 
WHEN '3' THEN '3' 
END,`sort` = CASE `id` 
WHEN '1' THEN '1' 
WHEN '2' THEN '3' 
WHEN '3' THEN '5' 
END WHERE `id` IN ('1','2','3')

Diese Situation ist einfacher und effizienter.

Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.

Verwandte Empfehlungen:

So generieren Sie schnell moderne Formulare mit PHP

Das obige ist der detaillierte Inhalt vonPHP-Batch-Update. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn