Rails中destroy_all和delete_all的差别
2016-06-06 16:44
483 查看
当项目达到了一定的水平之后,有些中间表的数据就可以不用保留了,很占用磁盘空间,但是为了以后不用手动清理,毕竟人都是懒的,特别懒,就需要程序自动清理空间。
Rails删除一个Model对应的表的某些数据有delete_all和destory_all两种方法,那么用哪儿种合适呢?
我们查找一下源码:
delete_all
# File activerecord/lib/active_record/relation.rb, line 452
def delete_all(conditions = nil)
invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select { |method|
if MULTI_VALUE_METHODS.include?(method)
send("#{method}_values").any?
else
send("#{method}_value")
end
}
if invalid_methods.any?
raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
end
if conditions
where(conditions).delete_all
else
stmt = Arel::DeleteManager.new(arel.engine)
stmt.from(table)
if joins_values.any?
@klass.connection.join_to_delete(stmt, arel, table[primary_key])
else
stmt.wheres = arel.constraints
end
affected = @klass.connection.delete(stmt, 'SQL', bind_values)
reset
affected
end
end
destory_all:
# File activerecord/lib/active_record/relation.rb, line 398
def destroy_all(conditions = nil)
if conditions
where(conditions).destroy_all
else
to_a.each {|object| object.destroy }.tap { reset }
end
end
前者的意思是一条sql语句删除所有的数据,比如:
<pre name="code" class="sql"><pre name="code" class="sql">delete from table_name where create_at > '2016-06-06 11:11:11'<span style="font-family: Arial, Helvetica, sans-serif;">;</span>
后者的意思是一条一条的删除:
delete from table_name where id=111;
我们找个rails的项目确认一下。
delete_all
2.1.1 :015 > ValidateStat.where('id > ?',4508).delete_all
SQL (1.4ms) DELETE FROM `validate_stats` WHERE (id > 4508)
destroy_all:
ValidateStat.where('id > ?',4504).destroy_all
ValidateStat Load (1.3ms) SELECT `validate_stats`.* FROM `validate_stats` WHERE (id > 4504)
(0.5ms) BEGIN
SQL (0.8ms) DELETE FROM `validate_stats` WHERE `validate_stats`.`id` = 4506
(0.5ms) COMMIT
(0.4ms) BEGIN
SQL (0.7ms) DELETE FROM `validate_stats` WHERE `validate_stats`.`id` = 4508
(0.4ms) COMMIT
这样更明显的看出区别了吧,达到的效果一样但是中间过程是不一样的,Rails为什么设计两个方法呢?什么情况下该用delete_all,而什么情况下该用destroy_all呢?
这样设计很明显是有用途的,delete_all是一条sql语句删除,如果删除的数据量太多的话,锁表的时间就会很长,会影响对表的使用,如果删除出现问题,回滚起来代价也比较大,但是少了很多网络IO,网络开销就比较小。后者是先查出所有的数据之后再一条一条的按照主键删除,几乎不会锁表,但是网络开销就比较大,同样的数据量的话,delete_all删除的速度更快些。
根据自己的数据量以及使用的场景选择合适的方法就好,一般情况下问题都不大。
Rails删除一个Model对应的表的某些数据有delete_all和destory_all两种方法,那么用哪儿种合适呢?
我们查找一下源码:
delete_all
# File activerecord/lib/active_record/relation.rb, line 452
def delete_all(conditions = nil)
invalid_methods = INVALID_METHODS_FOR_DELETE_ALL.select { |method|
if MULTI_VALUE_METHODS.include?(method)
send("#{method}_values").any?
else
send("#{method}_value")
end
}
if invalid_methods.any?
raise ActiveRecordError.new("delete_all doesn't support #{invalid_methods.join(', ')}")
end
if conditions
where(conditions).delete_all
else
stmt = Arel::DeleteManager.new(arel.engine)
stmt.from(table)
if joins_values.any?
@klass.connection.join_to_delete(stmt, arel, table[primary_key])
else
stmt.wheres = arel.constraints
end
affected = @klass.connection.delete(stmt, 'SQL', bind_values)
reset
affected
end
end
destory_all:
# File activerecord/lib/active_record/relation.rb, line 398
def destroy_all(conditions = nil)
if conditions
where(conditions).destroy_all
else
to_a.each {|object| object.destroy }.tap { reset }
end
end
前者的意思是一条sql语句删除所有的数据,比如:
<pre name="code" class="sql"><pre name="code" class="sql">delete from table_name where create_at > '2016-06-06 11:11:11'<span style="font-family: Arial, Helvetica, sans-serif;">;</span>
后者的意思是一条一条的删除:
delete from table_name where id=111;
我们找个rails的项目确认一下。
delete_all
2.1.1 :015 > ValidateStat.where('id > ?',4508).delete_all
SQL (1.4ms) DELETE FROM `validate_stats` WHERE (id > 4508)
destroy_all:
ValidateStat.where('id > ?',4504).destroy_all
ValidateStat Load (1.3ms) SELECT `validate_stats`.* FROM `validate_stats` WHERE (id > 4504)
(0.5ms) BEGIN
SQL (0.8ms) DELETE FROM `validate_stats` WHERE `validate_stats`.`id` = 4506
(0.5ms) COMMIT
(0.4ms) BEGIN
SQL (0.7ms) DELETE FROM `validate_stats` WHERE `validate_stats`.`id` = 4508
(0.4ms) COMMIT
这样更明显的看出区别了吧,达到的效果一样但是中间过程是不一样的,Rails为什么设计两个方法呢?什么情况下该用delete_all,而什么情况下该用destroy_all呢?
这样设计很明显是有用途的,delete_all是一条sql语句删除,如果删除的数据量太多的话,锁表的时间就会很长,会影响对表的使用,如果删除出现问题,回滚起来代价也比较大,但是少了很多网络IO,网络开销就比较小。后者是先查出所有的数据之后再一条一条的按照主键删除,几乎不会锁表,但是网络开销就比较大,同样的数据量的话,delete_all删除的速度更快些。
根据自己的数据量以及使用的场景选择合适的方法就好,一般情况下问题都不大。
相关文章推荐
- 红宝石(Ruby)史话
- Ruby on Rails所构建的应用程序基本目录结构总结
- Ruby on Rails中jquery_ujs组件拖慢速度的问题解决
- 浅谈Rails 4 中Strong Parameters机制
- Ruby中require、load、include、extend的区别介绍
- Ruby on Rails中的ActiveResource使用详解
- 关于Ruby on Rails视图编写的一些建议
- Ruby中的p和puts的使用区别浅析
- Ruby on Rails中的ActiveRecord编程指南
- 对优化Ruby on Rails性能的一些办法的探究
- 简单对比分析Ruby on Rails 和 Laravel
- Ruby中的block、proc、lambda区别总结
- Redis和Memcached的区别详解
- Lua中调用函数使用点号和冒号的区别
- Lua中关于求模与求余的区别介绍
- 在 Ubuntu 12.04 Server 上安装部署 Ruby on Rails 应用
- Ruby on Rails下的图像处理入门教程
- 详解Ruby on Rails中的Cucumber使用
- TMP、TEMP和TMP文件区别解析
- C#基础语法:结构和类区别详解