提供各种领域的最佳更新实践

时间:2016-11-23 18:40:20

标签: php mysql algorithm pdo

我试图找出更新mySQL表的最佳方法。

以下是我现在正在做的事情。 让我们假设该表包含4个字段(colA,colB,colC,colD)。 有一个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; } .. } } 类有一些特殊属性来指示使用按位运算符编辑的属性。

ElementAdaptor

该元素将被发送到PDO Adapter类interface ElementAdaptor { public function save(Element $element); }

$element->editedWhat

ElementAdaptor :: save()将读取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); }; } 属性并动态创建SQL片段。

{{1}}

坦率地说,我没有测试过这段代码,但我知道经过一些调试后它才能正常工作。

我想知道的是,根据已更改的内容动态更新字段的好方法是什么?我对自己的代码没有足够的信心,因为我从互联网上学到了这一点。虽然经过几年的长期练习和很好的例子,却无法相信自己,因为它没有经过任何人的修正。如果还有其他方法可以达到同样的效果,请提供帮助。

1 个答案:

答案 0 :(得分:1)

足以保存内存和PHP执行速度。有时(通常是?)根据具体情况(重载数据库活动或流量),最好保留原始值的副本,并通过比较旧/原始值与旧值来确定已修改的内容。

基本原理:大多数情况下,创建Web服务器集群比创建数据库服务器集群更容易(数据库级别的复制,一致性等很难.Web服务器很少需要 作为数据库的持久性/一致性级别,尤其是RESTfull /无状态服务)。

这就是说:数据库比Web服务器更容易成为瓶颈,因此“支付Web服务器资源”来保护数据库服务器更有意义。

[已编辑]:例如,您有许多使用相同数据库服务器的Web服务器,可能是同一个数据库。由于DB服务器可能是瓶颈,因此您希望尽可能地保护它(事务数量,如果数据库主机没有与WebServer相同的计算机托管,则为数据库主机带宽)。

在这种情况下,您牺牲WebServers上的计算能力/内存来检测在将请求发送到服务器之前需要保存的绝对最小变化:

  • “脏字段位掩码”方案仅检测字段是否至少被触摸过一次,但是如果我将字段设置为立即或在一系列操作之后设置为相同的值(假设原始A = 2,然后我设置A = 3并恢复到A = 2),即使不需要,也会要求DB服务器对该字段进行更新。

  • “与原始副本比较”方案将牺牲WebServer上的资源:内存(保留原始内容)和CPU电源(在保存之前执行比较)。但它绝对可以保护数据库服务器免受不必要的更新。

另外,小挑剔:

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