2016-11-23 4 views
3

Я пытаюсь выяснить, что является лучшим способом обновить таблицу mySQL.Лучшая практика для обновления с предоставлением различного количества полей

Вот что я делаю сейчас. Предположим, что таблица состояла из 4 полей (colA, colB, colC, colD). Объект Element. Объект будет содержать значение каждого столбца. Element класс имеет специальное свойство, указывающее, какое свойство редактировалось с помощью побитового оператора.

class Element { 
    const FLAG_EDIT_A = 1; 
    const FLAG_EDIT_B = 2; 
    const FLAG_EDIT_C = 4; 
    const FLAG_EDIT_D = 8; 

    public colA, colB, colC, colD; 
    protected $editedWhat = 0; 

    public function __set($varName, $value) { 
     $this->$varName = $value; 
     if($varName === 'colA') { 
      // If I change colA, FLAG_EDIT_A will be added to $editedWhat. 
      // However, if I edit colA twice, FLAG_EDIT_A must NOT be 
      $this->editedWhat += ($this->editedWhat & self::FLAG_EDIT_A)? 0 : self::FLAG_EDIT_A; 
     } 
     .. 
    } 
} 

Элемент будет отправлен в класс PDO адаптер ElementAdaptor.

interface ElementAdaptor { 
    public function save(Element $element); 
} 

ElementAdaptor :: сохранить() прочитает $element->editedWhat свойство и динамически создавать фрагмент SQL.

public function save(Element $element) { 
    // .. 
    if($element->editedWhat & Concept::FLAG_EDIT_A) { 
     $SQL_Array[] = 'colA=:A'; 
    }; 
    // ..etc.. 

    if(count($SQL_Array) > 0) { 
     $SQL .= implode(', ', $SQL_Array).' '; 
    } else { 
     return false; 
    }; 
    // ..etc.. 

    // Declare prepared statement. 
    if($element->editedWhat & Concept::FLAG_EDIT_A) { 
     $stmt->bindValue(':A', $concept->colA); 
    }; 
} 

Откровенно говоря, я не тестировал этот код, но я знаю, что он будет работать после нескольких отладочных операций.

Что мне интересно, это хороший способ обновить поле динамически в соответствии с тем, что было изменено? У меня нет достаточной уверенности в моем коде, потому что я узнал об этом из интернета. Хотя долгая практика за несколько лет и хорошие примеры, я не могу поверить себе, потому что это сделано без коррекции. Если есть другой способ добиться такого же результата, пожалуйста, помогите.

ответ

1

Хорошо подходит для сохранения памяти и скорости выполнения PHP. В зависимости от обстоятельств (активности базы данных большой нагрузки или трафика) иногда (часто?) Может быть лучше сохранить копию исходных значений и решить, что было изменено путем сравнения старого/исходного значения со старым.

Обоснование: в большинстве случаев проще создать кластер веб-серверов, чем кластер серверов баз данных (репликация, согласованность и т. Д. На уровне базы данных сложна. Веб-сервер редко должен быть , что уровень сохранности/согласованности как базы данных, особенно с помощью служб RESTfull/stateless).

Это означает, что база данных, скорее всего, станет узким местом, чем веб-сервер, поэтому «оплата ресурсов веб-сервера» для защиты сервера db имеет смысл чаще, чем нет.

[Редактировано]: например, у вас много WebServers, использующих один и тот же DB-сервер, возможно, одну и ту же базу данных. Поскольку БД-сервер потенциально является узким местом, вы хотите как можно больше защитить его (количество транзакций, пропускную способность для хоста БД, если он не размещен на том же компьютере, что и WebServer).

В такой ситуации, вы приносите в жертву вычислительной мощности/памяти на веб-сервере, чтобы обнаружить абсолютные минимальные изменения, которые должны быть сохранены перед отправкой запроса на сервер:

  • «грязное поле Bitmask» схема будет определять, было ли какое-либо поле затронуто хотя бы один раз, но если я устанавливаю поле в одно и то же значение сразу или после последовательности операций op (скажем, оригинал A = 2, тогда я устанавливаю A = 3 и вернусь к A = 2), вы запросите сервер БД для обновления в этом поле, даже если это не обязательно.

  • Схема «сравнение с оригинальной копией» пожертвует ресурсами на WebServer: память (чтобы сохранить оригинал) и мощность процессора (чтобы выполнить сравнение непосредственно перед сохранением).Но он абсолютно защитит DB-сервер от ненужных обновлений.

Кроме того, незначительные придираться:

 // If I change colA, FLAG_EDIT_A will be added to $editedWhat. 
     // However, if I edit colA twice, FLAG_EDIT_A must NOT be 
     // $this->editedWhat += ($this->editedWhat & self::FLAG_EDIT_A)? 0 : self::FLAG_EDIT_A; 

     // Isn't this simpler? 
     $this->editedWhat = $this->editedWhat | self::FLAG_EDIT_A; 

bitwise ops См

+0

Спасибо. Я понимаю побитовый оператор, но не уверен, поэтому ваш nitpick очень полезен для убеждения в том, что то, что я знаю, прав. Однако я не могу понять ваше описание после «Обоснования». – GatesPlan

+1

@GatesPlan Отредактировано, чтобы предоставить больше примеров. Теперь понятно? –

+0

Да! Это действительно полезно. Использование побитового оператора называется грязной полевой битовой маской, не так ли? Он выглядит мудрым, но на самом деле не сравнивает каждое значение, поэтому может иметь исключение. «битмакс грязного поля» может сохранить мощность процессора, но потенциально использовать большее количество БД. В определенной ситуации фактическое сравнение с оригинальным значением более разумно. Спасибо Adrian ^^ – GatesPlan

Смежные вопросы