ruby on rails爬坑(二):Active Record数据库查询

一,相关资料

不多说,精髓都在文档里。文档如下:

- rails官方:Active Record 查询

二,遇到的问题

先说问题:

#下面两条语句完成了相同的功能,可是性能有所差别
Mission.where(" title = 'test' ")[0]
Mission.where(" title = 'test' ").first #better

我们用rails来打造一个内部运营使用的CMS(content management system),既然是内容运营,那肯定少不了和数据库打交道。之前有位同事和我说了一句很有道理的话,在这里分享一下:

CMS可以看作数据库的一个映射,通过在CMS上的操作来操纵数据库里的数据。

对Active Record感兴趣的朋友可以直接看上面的文档,或者找一下英文的官方文档(不知道英文的会不会更新快点,交替着看吧,毕竟自己以后也是要写文档的)。请注意:

这篇博客不会介绍Active Record的每一个方法,官方文档有,不缺我这个搬运工,我只聊聊我遇到的问题及一些想法。

最近写了一些rails数据库查询的代码,说实话rails在数据库增删改查方面怎么太好使了,将Mysql的方法封装得很完整,也考虑到很多性能相关的问题,比我之前接触过的nodeJS要简单一些(当然,接触不多,只是第一印象,不是定论)。但也正是rails在这方面的便捷以及ruby自由的语法给我带来了一些问题,作为初学者,我第一时间考虑的是某个功能怎么实现。随着写的代码多了,也开始思考为什么是这样,换种做法有怎样?这些问题。

三,解决方法及思考

Mission.where(" title = 'test' ")[0]
Mission.where(" title = 'test' ").first #better

以前我都习惯用第一种,正常运行,没想太多。后来也陆续看了一些别人的代码,发现别人都用第二种,于是我好奇两者的差别在哪,做了个小测试,分别运行这两条语句,看看控制台输出相应的SQL语句是什么。结果如下:

Mission.where(" title = 'test' ")[0]
# SELECT "missions".* FROM "missions" WHERE (title = "test")

Mission.where(" title = 'test' ").first #better
# SELECT  "missions".* FROM "missions" WHERE (title = "test") LIMIT 1

显然,第二种方法性能要好一些,由对应的SQL语句可以看出,第一种方法是获取了所有满足条件的数据,再取出第一条;第二种方法是获取满足条件的第一条数据,只返回这一条。至于为什么是这样的,看文档:

Model.find(options) 方法执行的主要操作概括如下:
1,把指定的选项转换成等价的 SQL 查询语句;
2,执行 SQL 查询,从数据库中获取结果;
3,为每个查询结果实例化一个对应的模型对象;
4,如果有 after_find 回调,再执行 after_find 回调;

文档中以find为例子讲解了数据库查询过程,其余的也类型,重点是:“把指定的选项转换成等价的 SQL 查询语句”,而上面的 .first 正是查询的一种选项,而 [0] 不是,所以对应生成的SQL语句不同,性能也不同,第二种方法只返回了一条数据,性能自然要好一些,只是数据量较少的时候不明显。

其实解决问题的首要做法是:

认真看文档。

而遇见问题的最好做法是:

多写代码。

那解决问题的终极要义是什么?

我的理解是,看问题背后的本质是什么,程序是怎么运行的。

上面都是一些比较空的话,但也是感悟,说些实在的。

rails运行时多看控制台的输出,既然是输出,输出也是一种有用的信息,能帮助我们更好地理解rails,当然,看源码估计是以后少不了的。

注意:rails在development模式下(用rails s或rails s -e development)才会将信息输出到控制台,至于怎么配置,我试着改了一下config相关的文件,在test模式下没生效,会再研究一下。

四,题外

这只是个小问题,也许不值得写篇博客,但希望记录问题的解决思路。关于查询还有个问题在研究中,后面会更新这篇博客。

寒假正式开始,也快要过年了,新年快乐,加油。

发布了32 篇原创文章 · 获赞 87 · 访问量 15万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章