[mysql]MySQLはUPDATE文やDELETE文にORDER BY句やLIMIT句を使えるが、使わないほうがいい

徒然草2.0

結論から言うと、MySQLではDELETE文やUPDATE文にORDER BY句やLIMIT句を使うことができる。

つまり、実行した結果をソートした順のレコードへ、DELETEやUPDATEの処理を適用することが可能ということだ。

以前に自分もWebアプリケーション内で使ったことがあるのだが、これはSQL標準におそらくないものでありMySQL独自の拡張構文であり(軽く調べた限り)PostgreSQLやOracleでは使えない。

端的に何のレコードに対して削除や更新をかけているのか分かりにくい。MySQLにずぶずぶな人(?)で、この機能を上手く使う自身がある(責任はコードを書いた人が責任をとる)のならば使用しても構わない。しかし、MySQLでしか使えないという意味では、バッドノウハウの書き方になるだろうと私は思う。

なぜなら、そもそもDELETEやUPDATEがSELECTやVIEWと同様にリスト取得した後の先頭レコードに対して処理が掛かる…という手続き型言語的な順番概念がない=1トランザクションなところががRDBの分かりやすいところが、分かりにくくなってしまうからだ。(Where句で絞り込まれた対象レコードへ一律処理がかかるという常識が、通用しなくなると混乱する人も出てくると言ってもいい)

(補足…同じ意味のことを更に繰り返し述べるが)

レコードを追加した最終日のレコード順(追加した日の古い順)に削除したいのならば、delete from users order by desc user_id limit 1;みたいなクエリを実行して実現可能だろう(ソラで書いたSQLでためしていないが)、間違えた時にどれくらいダメージを被るかわからないし、SQLを見てぱっと見で意図がわかりにくい(と思う)だから、サブクエリで条件抽出したほうが無難だろう。(incrementalなuser_idをlast_delete_dateにしたら解決というものでもない)

delete from users where user_id = (select user_id from users order by desc user_id limit 1);

※クエリビルダでオブジェクティブに実行したい?それがそれでで文脈的に分かりやすいなら…どうぞ、そうしてくださいと言わざる得ない。

コメント

タイトルとURLをコピーしました