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

根据自己的数据量以及使用的场景选择合适的方法就好,一般情况下问题都不大。



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值