Do You PHP はてブロ

Do You PHPはてなからはてブロに移動しました

SQLのオレオレコーディング規約

via. ホームページ移転のお知らせ - Yahoo!ジオシティーズ

読んでて懐かしかった(?)ので、なんとなくエントリ。。。
下手すると宗教戦争になりかねないコーディング規約ですが、複数人で開発する場合、プログラミング言語だけではなく、SQLにもあった方が良いのは言うまでもありません。
今のところ、オレオレ規約で書いてるわけですが、ベースとなってるのは最初に入社した会社の先輩の書き方です。で、SQLプログラミング作法の"コーディング・ルール"にある項目に沿って、それぞれどんな感じで書いてるのか晒してみます。

コメント

ハイフン2つ(--)も複数行コメント(/* 〜 */)も両方使ってます。後者はjavadocっぽく書いてます。

/**
 * ○○○○を日毎に集約
 *
 * @todo チューニング
 */

インデント

スペース4つ。基本的に、"意味が切れる"予約語(FROM、WHERE、ANDなど)で改行を入れてます。ただし、SQLプログラミング作法にあるような、カラム名の開始位置を揃えたりしません。前述の先輩はこういうふうに揃えてましたが、実際これって面倒じゃないですか?

SELECT
       col_1,
       col_2,
       col_3,
       COUNT(*)
  FROM tbl_A
 WHERE col_1 = 'a'
   AND col_2 = ( SELECT MAX(col_2)
                   FROM tbl_B
                  WHERE col_3 = 100
            )
 GROUP BY
       col_1,
       col_2,
       col_3

上と同じSQLなら、こんな感じで書くと思います。

SELECT
    col_1,
    col_2,
    col_3,
    COUNT(*)
FROM tbl_A
WHERE col_1 = 'a'
AND col_2 = (SELECT MAX(col_2)
             FROM tbl_B
             WHERE col_3 = 100)
GROUP BY
    col_1,
    col_2,
    col_3

極端な話、デバッグログから拾ったSQLをざっと整形するときはこんな感じ。まあ、マクロ使って機械的に整形させてるので。。。

SELECT
    col_1,
    col_2,
    col_3,
    COUNT(*)
FROM
    tbl_A
WHERE col_1 = 'a'
AND col_2 = (
    SELECT
        MAX(col_2)
    FROM
        tbl_B
    WHERE col_3 = 100)
GROUP BY
    col_1,
    col_2,
    col_3

カンマ(,)

ところで、このカンマというやつ、要素の後ろに置く、と思っていないでしょうか?

はい、そのとおりです:-) 必ず、後ろに置いてます。

スペース

これは、ほぼ同じです。等号・不等号の前後、カンマの後ろには必ず入れてます。ただし、カッコの内側に入れてません。

SELECT *
  FROM   tbl_A A, tbl_B B
 WHERE  ( A.col_1 >= 100 OR A.col_2 IN ( 'a', 'b' ) )
   AND  A.col_3 = B.col_3;

ならば、

SELECT *
FROM tbl_A A, tbl_B B
WHERE (A.col_1 >= 100 OR A.col_2 IN ('a', 'b'))
AND A.col_3 = B.col_3;

になります。エディタにも依りますが、対応するカッコを強調表示できたりしますから、そんなにスペースを空けなくてもいいかな、と。

大文字と小文字

これはそのまま

予約語は大文字、列名やテーブル名は小文字

にしてます。なので、Propelが作るSQLは好きじゃないです。あと、テーブルには必ず別名を付けてて(参照するテーブルが1つの場合でも)、別名は小文字で付けてます。昔は、アルファベット1〜2文字で付けてました。

標準語を話そう

あー、確かにOracleの"DECODE"や"NVL"、"(+)"は使ってたなぁ。現在は、PostgreSQLなので、"CASE"、"COALESCE"、"LEFT OUTER JOIN"使ってます。また、"INNER JOIN"は『必ず書く派』です。

相関サブクエリは避ける

まあ、ケースバイケースですが、

EXISTS で書いた方が速く動作する可能性が高くなります

のはありますね。昔のOracleではそうでした。PostgreSQLの場合、EXISTSよりもLIMIT 1の方が早い場合もあるようです。

番外:プログラミング言語SQLを埋める場合

文字列としてSQLを組み立てる場合、最後に必ずスペースを入れてます。

/**
 * 文字列の最後にスペースをかならず入れる
 */
$query = "SELECT e.empno, e.ename "
       . "FROM emp e "
       . "WHERE e.name LIKE 'S%' ";