我试图找出更新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}}
坦率地说,我没有测试过这段代码,但我知道经过一些调试后它才能正常工作。
我想知道的是,根据已更改的内容动态更新字段的好方法是什么?我对自己的代码没有足够的信心,因为我从互联网上学到了这一点。虽然经过几年的长期练习和很好的例子,却无法相信自己,因为它没有经过任何人的修正。如果还有其他方法可以达到同样的效果,请提供帮助。
答案 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