sqlのスタイルガイドについて、自分の経験や様々な記事の内容を踏まえて自分なりにベストなものを考えてみた。
予約語/関数は、大文字か小文字か?
予約語は大文字を使うという意見が多い中、私は"小文字"をオススメします。
小文字をオススメする理由
大文字より小文字の方が表示に使う面積を削減できる!
大文字の方が小文字に比べて面積を取るので予約語が増えてくるとクエリ全体が窮屈な感じになって見にくくなると思っています。
レビューのコストを削減する!
予約語を大文字にするスタイルで統一していたとき、たまに「あれ?これ予約語だけど小文字のままだよ」みたいな指摘をする機会がありました。レビューする側も実装する側も予約語がちゃんと大文字になっているかという観点で気にしないといけないためその分コストがかかっていました。小文字ならそんなことは考えなくてOKです。
例を以下に書きます。
-- 大文字の例
SELECT
id,
email,
name
FROM
users
WHERE
users.id = '1'
;
-- 小文字の例
select
id,
email,
name
from
users
where
users.id = '1'
;
予約語が少ないうちは大文字でも違和感ない。
次に予約語が増えた場合の例を書きます。 大文字の場合は少し詰まっている印象を受けます。
-- 大文字の例
SELECT
id,
CASE
WHEN users.email IS NULL
THEN 'emailなし'
ELSE
THEN email
END AS email,
REPLACE(address, "住所", ""),
CONCAT(first_name, last_name) as name
FROM
users
WHERE
users.id = '1'
;
-- 小文字の例
select
id,
case
when users.email is null
then 'emailなし'
else
then email
end as email,
replace(address, "住所", "")
concat(first_name, last_name) as name
from
users
where
users.id = '1'
;
XX句の後は改行&先頭を揃える
以下は後ろを改行して先頭は全て揃えています。
句を先頭に持ってくることで、句の切れ目がわかりやすくなり読みやすくなります。
- select
- from
- where
- group by
- order by
select
id,
email,
name
where
users
order by id
;
where句のandについて
where句のand後ろは改行&where句と同じインデント
句で改行という書き方は結構あると思いますが、where句のandをwhereと同じインデントで書くというのはないようですので以下に例を書きます。
-
where句のandの後ろに条件を書く例
気になる点:where句の最初の条件だけ他とずれてみえてしまう。
where
users.id > 1
and users.email is not null
and users.point > 1000
and users.active_flag = true
order by id
;
-
where句のandの後は改行
気になる点:andと条件が同じインデントで見づらい。
where
users.id > 1
and
users.email is not null
and
users.point > 1000
and
users.active_flag = true
order by id
;
-
where句のandの後は改行&インデントはwhere句と同じにする
条件とandのインデントを分けて条件だけを見れるようになりました!
where
users.id > 1
and
users.email is not null
and
users.point > 1000
and
users.active_flag = true
order by id
;
##文末のセミコロンは最終行に書く
これは他の記事などでもみなさん同じことを書かれていました。
クエリを作成する際に、セミコロンは最終行に書くようにした方が、セミコロンがある位置は必ず先頭と決まるのでつけ忘れのミスを防止できます。
select
id,
name
from
users
;
-- 最終行につけない場合の例
-- バッチ処理などでクエリを続けて何本か書くときにつけ忘れてしまいます。。
-- 以下は2番目のクエリのセミコロンを忘れている例
select
id,
email
from
users;
select
id,
email
from
users
select
id,
email
from
users;
##インデントはスペース2つ
スペース2つが全体としてある程度まとまって見える。それより多いと逆に読みにくくなる。
-- スペース2つ
select
id,
name
from
users
where
id = 1
and
name = 'test'
;
-- スペース4つ
select
id,
name
from
users
where
id = 1
and
name = 'test'
;
テーブルには適切な別名をつける
長いテーブル名なんて作らなければいい。と言ってしまいたいところなんですが、すでに長いテーブル名のものがあったり現実はそうもいかない。。
別名は頭文字1文字とする書き方などもありますが省略しすぎると、コードを読みながら何のテーブルなのかが頭に入って来ないので極端に削らずある程度ルールを持たせて初見でも意味が推測できる略し方くらいがいいかなと思います。3文字で書くなど厳密に決めず別名はある第三者がみてわかる。長すぎない。無駄がない。くらいで十分かと。
以下の場合は、user_xxxのテーブルを複数結合するケースです。この場合は、user_xxxというテーブルしか登場してこないのでその後ろ(user_xxxのxxx)を別名としてしまえばいいと思います。
select
setting.id,
log.id,
hist.id
from
user_setting setting,
user_log log,
user_history hist
where
setting.user_id = log.user_id
and
log.user_id = hist.user_id
;
以下の場合は、user_logとaccess_logと似た名前を結合するケースです。この場合は、logという別名をつけるわけにはいかないのでu_xxxという別名をつけています。access_logはa_log。
select
u_setting.id,
u_log.id,
u_hist.id,
a_log.id
from
user_setting u_setting,
user_log u_log,
user_history u_hist,
access_log a_log
where
u_setting.user_id = u_log.user_id
and
u_log.user_id = u_hist.user_id
and
u_log.user_id = a_log.user_id
;
内部結合(INNER JOIN)の書き方ついて
内部結合の場合、inner join句を使用せずに記載することもできます。(mysql、
sqlserverで確認済み)
from句に結合したいテーブルを書いてwhere句で結合条件を書けばOKです。
この書き方の場合のポイントは以下です。
inner join句がないので少ないコード量でかける
where句で結合条件をまとめて書くので結合するテーブル数が多いと一部のテーブルの結合条件が抜けてしまうことがある(抜けているのに気がつかない)
外部結合の場合はleft join句を使用する必要があるのでこの書き方ができるのは内部結合の場合のみ
2つか3つくらいのテーブルを内部結合をする場合にはこの書き方の方が速いですが、結合するテーブルが増えてきたときは、向いていないかもしれません。
-- inner join句を使う
select
id,
name
from
users
inner join books
on (users.id = books.user_id
and
users.active_flg = true)
;
-- inner join句を使わずに内部結合
select
id,
name
from
users,
books
where
users.id = books.user_id
and
users.active_flg = true
;
以上です。ここにあるのを正解としたい訳ではなく、良いと思うものがあれば参考にしていただければと思います。また以下記事も非常に参考になりました。
https://qiita.com/taise/items/18c14d9b01a5dfd6d35e