当项目达到了一定的水平之后,有些中间表的数据就可以不用保留了,很占用磁盘空间,但是为了以后不用手动清理,毕竟人都是懒的,特别懒,就需要程序自动清理空间。
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删除的速度更快些。
根据自己的数据量以及使用的场景选择合适的方法就好,一般情况下问题都不大。