小心 Laravel update 数据的坑
通常我们更新数据有以下几种方法:
方法 1
$model = Model::find($id);
$model->field1 = $value1;
$model->field2 = $value2;
$model->save();
方法 2
Model::find($id)
->update([
'field1' => $value1,
'field2' => $value2,
]);
方法 3
Model::query()
->where('id', $id)
->update([
'field1' => $value1,
'field2' => $value2,
]);
三种方法都可以更新数据,如果是你,你会选择哪种方法?或者说哪个方法是性能最好的?
以下为更新内容,揭晓答案:
肯定不是标题党哦,本来是想个大家一个选择的过程,一起讨论。
答案是选择方法3,方法3 仅生成一条 SQL 如下:
update table set field1=value1, field2=value2 where id = $id;
方法1,方法2,都是形成两条SQL,会多一次查询语句:
select * from table where id = $id limit 1;
update table set field1=value1, field2=value2 where id = $id;
@Imuyu 提到 find 可能返回空,也是个值得注意的地方,直接update 没有 id 也就没有更新内容了,也会减少一次判断。
这里主要想分享下,多去关注 Elequent 的具体SQL内容,用的时候很爽,但如果没搞清楚底层实现,也会造成很多优化的麻烦。
坑在哪
坑呢?
标题党?
???
说好的坑呢? 正好过来假装准备来填坑来着
可能就是
find
会返回空吧!方法三不会触发相关的更新事件 如果有用到的话 找都没法找 不可取 方法一/二 虽然会多一次查询 但是也不会影响太多 性能上是可以接收的
方案一中的
find
并不仅仅是为了更新数据用的,实际的开发过程中,会有逻辑判断,然后再决定是否需要更新这个,,,也是坑吗,,,前面两种,先查询出模型,那肯定会有一条 select,,,
@largezhou 如果你直接用方法3,那就当我没说。如果你用了方法2,那就值得思考下了。
抛开Observe不谈,单纯更新数据,我想应该大多数人都是方法2的写法吧。
真没这么用过方法2。。。
方法1和方法3用的多
有点不同见解,我最常用的是方法1。
所以方法1和方法2执行的
SQL
是有可能只有SELECT
而没有UPDATE
的。以前经常会听到前辈们优化数据库的一个办法是先查询后修改,至于为什么从没有深入探究,恰巧上几天在社区看到一篇文章《浅入浅出MySQL》表锁 行锁 并发插入,恍然大悟,是因为写锁和读锁的优先级问题,所以我觉得ORM这种先查询后修改的方式对于高频率修改的数据库来说对程序更加健壮,至于那个查询引发的效率问题,应该可以忽略不计了。
最后,方法1和方法2确实有坑,可参考博客:Laravel 修改数据与原数据一样 导致没有执行sql,就是用了ORM后,又通过数据库方法修改数据库,导致ORM内的数据和数据表的数据不一致导致更新丢失字段。
方法2非链式操作还是经常用的
坑呢
如果有需要抛事件的时候 会选择方法1 ,不需要抛事件的时候 选择方法3
这个要看具体使用地方了
今天update用的方法三,但是采用了如下写法导致where子句没有生效,把我整表更新了,无语