您的位置:首页 > 大数据 > 人工智能

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删除的速度更快些。

根据自己的数据量以及使用的场景选择合适的方法就好,一般情况下问题都不大。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息