关于NotORM中limit()操作的特别说明

1. 背景

20150617.png


首先,感谢 落舞者 同学的发现和反馈。
其次,在这里为我们对NotORM不正确的修改表示歉意。

为了大家更确这其中的问题和日后正确的使用,这里将问题进行相关的说明和PhalApi最终对此的处理方案。

2. 之前对NotORM不正确的修改

代码位置:/PhalApi/NotORM/NotORM/Result.php line 48

修改前:
$return .= " OFFSET $offset";
修改后:
//$return .= " OFFSET $offset";
$return .= ",$offset"; //@dogstar 2014-10-24

3. 修改后的影响以及正确使用的方法

上面的修改主要是对传递两个参数时,两个参数的意义互换了,即:
limit(数量,开始位置)   变成了  limit(开始位置,数量)

但一个参数时,仍然是原来的意义,即:
limit(数量)

因此,正确的使用应该是:
$table->limit(10);  // limit 10   # 查询前10个



$table->limit(5, 10); // limit 5,10 # 从第5个位置开始,查询前10个




为了加深印象,这里再重复对比一次,正确的使用方式是:
->limit(数量)
->limit(开始位置,数量)


4. PhalApi的解决方案:保留现有的修改
如果对此数据库的limit操作进行调整的话,已上线的项目一旦更新升级框架后,原来使用limit()操作都会受影响。其中,最明显的两个可预测的故障场景是:

预测故障场景1:升级后,首页列表无任何数据显示!!!
这是由于通常在取第一页列表数据时,我们是这样编写代码的:
$table->limit(0, 100);  //未升级前是:从第0个位置开始,取100条纪录
但如果恢复OFFSET操作,会导致是从第100个位置取0条纪录!显然,接口就会不返回任何数据了!这显然对应用来说是一个灾难,特别在不知道这一个底层修改的话。

预测故障场景1:升级后,列表数据过多导致App加载崩溃
这个场景会发生在分页很多的时候,越到后面,取的数量越多,如:
$table->limit(9999, 100);  //未升级前是:从第9999个位置开始,取100条纪录
升级后如果不调整Model层的调用,就会变成从第100个位置开始取9999条纪录了!!!这显然也是一个灾难。

基于这样不可接受的故障预测,并且我们也一直努力坚持“做到100%向前兼容”,让项目可以放心升级PhalApi。

而且,即使我们做了修改通过各种途径知会各开发团队进行相应调整,我们也不能确保可以知会到全部的开发同学;即使我们全部通知了,项目也不一定能全部做出调整。

基于以上的考虑,我们做了个艰难的决定:保留现有的修改,不恢复OFFSET的使用


5. 再次深表歉意
非常感谢大家一直以来对PhalApi的关注和肯定,但这次确实是我们对MySQL的limit操作未完全洞察明白的情况下作了错误的修改,从而歪曲了NotORM原来的意思。也为对大家带来的困惑表示抱歉。

希望PhalApi继续可以和广大的项目一起慢慢成长!
 

2 个评论

我认为知错能改还是好同学,limit(数量,开始位置) 这样更科学
是的,但鉴于对已有项目的冲击,我们也只好尽最大的努力来保持向前兼容。这不是一个好的做法,而且这一切都源于我们的自身开发的问题。

要回复文章请先登录注册