我想出了一个有趣的概念,它允许开发人员创建与数据库无关的代码,但与 ORM 不同的是不会牺牲性能:
- 易于使用(如 ORM)
- db-agnostic:适用于 SQL、NoSQL、文件等
- 如果供应商允许,总是优化查询(sub-select,map-reduce)
结果是敏捷数据 - 数据库访问框架(详细解释请参见视频)。
使用与 DB 无关的代码和敏捷数据解决现实生活中的任务
- 从描述商业模式开始。
- 创建持久性驱动程序
$db
(DB 连接的一个花哨的词),它可以是 CSV 文件、SQL 或 LDAP。
- 关联模型
$db
并表达你的Action
- 执行
Action
此时,框架将根据数据库的能力确定最佳策略,映射您的字段声明,为您准备和执行查询,这样您就不必编写它们了。
代码示例
我的下一个代码片段解决了一个相当复杂的问题,即确定我们所有 VIP 客户的当前总债务是多少。架构:

接下来是与供应商无关的代码:
$clients = new Model_Client($db);
// Object representing all clients - DataSet
$clients -> addCondition('is_vip', true);
// Now DataSet is limited to VIP clients only
$vip_client_orders = $clients->refSet('Order');
// This DataSet will contain only orders placed by VIP clients
$vip_client_orders->addExpression('item_price')->set(function($model, $query){
return $model->ref('item_id')->fieldQuery('price');
});
// Defines a new field for a model expressed through relation with Item
$vip_client_orders->addExpression('paid')
->set(function($model, $query){
return $model->ref('Payment')->sum('amount');
});
// Defines another field as sum of related payments
$vip_client_orders->addExpression('due')->set(function($model, $query){
return $query->expr('{item_price} * {qty} - {paid}');
});
// Defines third field for calculating due
$total_due_payment = $vip_client_orders->sum('due')->getOne();
// Defines and executes "sum" action on our expression across specified data-set
结果查询 if$db
是 SQL:
select sum(
(select `price` from `item` where `item`.`id` = `order`.`item_id` )
* `order`.`qty`
- (select sum(`payment`.`amount`) `amount`
from `payment` where `payment`.`order_id` = `order`.`id` )
) `due` from `order`
where `order`.`user_id` in (
select `id` from `user` where `user`.`is_client` = 1 and `user`.`is_vip` = 1
)
对于其他数据源,执行策略可能会增加更多数据,但会始终如一地工作。
我认为我的方法是抽象数据库的好方法,我正在努力在 MIT 许可下实现它:
https://github.com/atk4/data