Наилучшая практика обновления с предоставлением различного количества полей


Я пытаюсь понять, как лучше всего обновить таблицу 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);
}

Элементадаптор::сохранить() будет читать $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);
    };
}

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

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

Author: GatesPlan, 2016-11-23

1 answers

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

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

Это означает: база данных с большей вероятностью будет выступать в качестве узкого места, чем веб-сервер, поэтому "оплата ресурсов веб-сервера" для защиты сервера БД чаще имеет смысл, чем нет.

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

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

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

  • " схема "сравнение с оригинальной копией" приведет к потере ресурсов на веб-сервере: памяти (для сохранения оригинала) и мощности процессора (для выполнения сравнения непосредственно перед сохранением). Но это абсолютно защитит сервер БД от ненужных обновлений.

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

        // 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;

См. побитовые операции

 1
Author: Adrian Colomitchi, 2016-11-24 23:30:01