こんにちは!新卒エンジニアのs0ush1nです。
入社してから半年が経ち、さまざまな業務を行う機会が増えました。
今回はその中でも担当することが多い、クエリをテーマにしてお伝えします。
これから社会人になる方や、初めて業務でデータベースを扱う方が、可読性が高くチーム開発でも使えるクエリを書けるようになることを目標にまとめます。
目次
- クエリとは
- クエリの可読性について
- SELECT文を使ったクエリの作成例
- UPDATE文を使ったクエリの作成例
- まとめ
クエリとは
クエリはデータベースに取得、更新、削除、挿入するための命令を指し、この記事ではSQLを一括りにクエリと呼称します。
クエリの例
条件:usersテーブルにname,ageカラムが存在
SELECT name, age FROM users WHERE age > 30;
簡単な例ですが、以上のクエリを書くことで
“usersテーブルからageが30以下のuserのnameとageを抽出”
が可能です。
クエリの可読性について
個人開発でとにかく動作するクエリを書けばよい、という要件であればどのような書き方をしても構いません。
しかし、社内のチーム開発という環境では可読性が要求されるようになります。
ここには大きく二点の理由が存在しています。
「実行・実装者が異なる際のリスク低減」と「レビュワーへの配慮」です。
実行・実装者が異なる際のリスクの低減
クエリの可読性が低い状態で異なる実行者に依頼すると、以下のリスクが高まります。
- 意図していないDBで実行してしまった
- クエリの実行順序を間違えてしまった
- 抽出結果が要件通りにならなかった
実行内容によってはデータが消えたり上書きされてしまうリスクを防ぎ、
組織ごとに存在している規約を守りながらクエリを書いていきましょう。
レビュワーへの配慮
チーム開発の特徴として、コードレビューが存在します。
チームメンバーにコードを共有し、内容に問題がないかをクエリの実行前に確認してもらう工程のことで、可読性も求められました。
可読性を高めておくことで、適切なインデントや説明、不適切なカラム名を使用していた場合に気づきやすいというメリットが存在し、リスクの低減が可能です。
明快なコードでお互い快く確認し合える環境を作りましょう。
SELECT文を使ったクエリの作成例
それでは、例を見ていきながら可読性を高めるクエリについて説明していきます。
/* アクティブなユーザーを抽出 条件: - testDB上で実行 - 18歳以上 - 2023年1月1日以降に登録 - ステータスが「active」 */ USE testDB; SELECT id AS 'ユーザーID', name AS '名前', email AS 'メールアドレス', age AS '年齢', registration_date AS '登録日', status AS 'ステータス' FROM users WHERE age >= 18 AND registration_date >= '2023-01-01' AND status = 'active' ;
このクエリの可読性を高めているポイントとして、条件説明・DB指定・インデント・ASによる命名があります。
条件説明
実行内容のタイトル、条件をコメントアウトにまとめます。
これにより、SQLファイルの中身を確認するだけで内容が理解できること、その他のドキュメントを確認しなくてもやりたいことが見えている状態になるため全体的な可読性に繋がります。
DB指定
phpMyAdminのようなGUI環境で実行をする場合、DB内のクエリ入力欄に入力することにより明示しなくても実行がされてしまう場合があります。
実行者が異なる場合、どのDBで実行すべきクエリなのかが伝わっていない可能性があるため、これを回避するためにもDB指定を推奨します。
インデント
命令文やその他の指定単位で分けてインデントを行います。
細分化することで可読性が向上し、条件網羅漏れや確認ミスといったリスクの軽減に繋がります
ASによる命名
直接的なクエリの可読性につながる訳ではありませんが、非エンジニアの方に共有するためのデータ抽出を行う場合はとくにカラム名ではなく一般名詞での命名が望ましいです。
user_typeといったカラム名が表に混じっていると、読みやすさに影響します。
1つのSELECT文で完結しているクエリのため元々ある程度可読性は高いですが、
可読性をより高める工夫をしておくことで長いクエリを作成する際も可読性を損なわず作成できるため常に意識して損はありません。
UPDATE文を使ったクエリの作成例
次は、データベースに変更を与えるUPDATE文のようなクエリの作成例です。
/* some_columnテーブルの全てのレコードのstatus_flagを1に更新する */ USE testDB; -- 更新前のフラグの状況を確認 SELECT e.id, e.status_flag, h.name FROM example_table e INNER JOIN hoge h ON e.some_column = h.some_column ; -- 全てのレコードのstatus_flagを1に更新 UPDATE example_table e SET e.status_flag = 1 FROM example_table e INNER JOIN hoge h ON e.some_column = h.some_column ; -- 更新後のフラグの状況を確認 -- フラグが全て1に変更されたかどうかを確認。 SELECT e.id, e.status_flag, h.name FROM example_table e INNER JOIN hoge h ON e.some_column = h.some_column ;
このクエリでは前述の条件説明、DB指定、インデントに加えてSELECT文の導入、エイリアス設定を行っています。
SELECT文の導入
“変更しようとしているカラムやテーブルが存在しているか?”
“変更したカラムやテーブルを更新できているか?”
ということを改めて確認するために変更の前後にSELECT文を設定します。
これにより実行者が具体的な内容を知らない場合にも変更を確認できるため、確実性を高めることが可能です。
エイリアス設定
エイリアスとは、テーブル名に別名をつけることで、1文字から設定することが可能です。
例ですが、user_attrebute_typeテーブルが存在した際にuとおいて、u.nameと表すこともできます。
まとめ
会社でクエリを扱う場合は、実行者が自分ではないことで理解しやすさ、ミスのなさが求められます。
そのため、私はクエリは手順書に近いのではないかと考えています。
まず明確さと一貫性が求められ、他のメンバーが理解しやすいように記述することが重要で、チームで扱う以上後から読んだ人がその意図や内容を理解できなければなりません。
また、どちらも正確に取り組むことで誰でも同じ結果が得られることから再現性が必要な点も似ていると考えます。
ひとつのコードと扱うのではなく、手順書を正確に書く気持ちで可読性を高めミスの少ない運用を行えたら良いですね!