使用OOP时,如果仍然遵循DRY原则,您通常会如何优化类似以下类的数据库性能?
class AccountExampleClass
{
private $_mysqli;
// Current account ID
private $_accountId;
public function loginActions()
{
// Stuff to do on login
// ...
// Store the current time in last_activity and last_login, using
// two queries instead of one.
$this->updateLastActivity();
$this->_updateLastLogin();
}
// Run on every pageview
public function updateLastActivity()
{
$this->_mysqli->query("UPDATE `accounts` SET `last_activity` = NOW()
WHERE `id` = $this->_accountId LIMIT 1");
}
// Only run on login
private function _updateLastLogin()
{
$this->_mysqli->query("UPDATE `accounts` SET `last_login` = NOW()
WHERE `id` = $this->_accountId LIMIT 1");
}
}
这只是一个快速的模型来说明问题。 last_activity和last_login字段都有一个更新数据库的方法,但有时需要更新它们(如loginActions方法所示)。通过使用多个查询,浪费了大量资源并且延迟增加。
有很多方法可以做到这一点,我现在可以想到。其中一些是可怕的,另一些是可用的。
这是一个清单:
在这种情况下,性能,复杂性和可维护性之间的最佳平衡是什么?
答案 0 :(得分:0)
我认为这里的答案是使用一个ORM层来为您处理这个问题,允许您更新对象属性,然后在完成后保留这些更改
在实体上调用persist方法不会立即导致 要在数据库上发出SQL INSERT。学说适用策略 称为“事务性后写”,这意味着它会延迟 大多数SQL命令,直到调用EntityManager#flush() 然后发出所有必要的SQL语句来同步你的对象 以最有效的方式与数据库,单,短 交易,保持参照完整性。
http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html
答案 1 :(得分:0)
不要先行优化,尤其是以增加复杂性为代价。我认为你对它添加大量开销的想法是错误的。
如果你真的想这样做,只需添加第三种方法(类似于updateBoth)或将所有这些选项滚动到一个接受基于你想要的模式的参数的方法中......
function updateTime($mode){
if ($mode == "login){}
else if ($mode == "activity"){}
else {
//update both
}
}
答案 2 :(得分:0)
当这样的项目开始时,许多新手程序员直接编写SQL语句就是常见的。更有经验的程序员,使用其他更复杂的库,如ORM,MVC,N-Tier层。
您可能想要开始使用ORM库,它们支持“创建类似代理的类”,并使用“使用对象来表示行的当前状态”。
对象关系映射(ORM)库,有时支持“使用对象来表示行的当前状态”方法,有时支持“多行或所有行”,具体取决于您要执行的操作。
其中一些,允许直接编写SQL作为最后的手段,altought,常用操作,插入,更新,查询,由方法处理。
如果需要,它们也可以帮助您更改数据库服务器,或者只更改表或字段的标识符。或者,当您使用具有相同结构/架构的多个数据库或多个表时。示例:Sales-January,Sales-February。
这些库可能有点复杂,但是,一旦你习惯了它们,它们会帮助你,处理更复杂的操作,比如你发布的那个。
只需2美分。