2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SQLアンチパターン インプリシットカラム

Posted at

インプリシットカラム

検索時のワイルドカード記号やインサート時の列名省略などクエリを省略することにより弊害が起こる場合がある。

目的:タイプ数を減らす

以下のようなユーザー情報があった際に全ての列を取得するにはどのような取得方法をするか。

User

user_id user_name user_email tel
1 TEST test@example.com 000-1111-2222

おそらく多くの人は

SELECT 
  user_id,
  user_name,
  user_email,
  tel,
FROM
  User;

ではなく、

SELECT * FROM User;

で、取得するかたが多いのではないでしょうか?
また、「User」テーブルの全列にデータを格納する際はどうするでしょうか。

INSERT INTO
  Users(user_id, user_name, user_email, tel) 
VALUES
  (2, "TEST2", "test2@example.com", "111-2222-3333");

上記のように全列名を記載しますか??
それとも以下のように列名を省略しますか??

INSERT INTO
  Users
VALUES
  (2, "TEST2", "test2@example.com", "111-2222-3333");

暗黙的に列名を指定できる際は列名を省略することも多いのではないか。
列名の多い場合やどうせ全列取得、挿入するなら手間だと感じ省略することもあるかと思う。

リファクタリングによる問題

user_id user_name user_email tel

先ほどのUsersテーブルに「age」列を追加することになった。

user_id user_name user_email tel age

テーブルに列が追加されたことを知らない場合、先ほど同様に以下のクエリにてデータを挿入しようとしたらエラーを返すようになった。

INSERT INTO
  Users
VALUES
  (2, "TEST2", "test2@example.com", "111-2222-3333");

このようにリファクタリングによって予期しない値が挿入される場合等ある。
また、列を削除して新たに追加した場合や、新たに追加した後に別の列を削除した場合などでは型さえ一致していればエラーを返さず本来想定していない列に別の列にの値を知らず知らずに挿入してしまうなども考えられる。

また、列が削除されている場合エラーを返すが明示的に列を指定していた方が原因究明がしやすい。

不要な列のみ除去

SQLには「指定した一部の列のみ除去した全ての列」を取得することができない。

  • 前列をワイルドカードで取得する
  • 明示的に必要な列のみ指定する

の2つの方法しかない。

アンチパターンを使用しても良い場合

  • テストや検証で素早くクエリを発行したい場合

解決策

列名を明示的に指定する

ワイルドカードや暗黙的な列指定をせず、必要な列名は明示的に指定する

謝りの防止

列名を明示的にすることで致命的なミスを防ぐことが目的。

  • テーブル定義の列の順番が変わっても明示的に指定していれば結果は一緒
  • INSERT時に予期せぬ列に挿入されることを防げる
  • テーブルから列が削除された際にしっかりとエラーで落ち、原因究明がしやすい

明示的に列名を指定することで誤った挿入や予期しない列順でのデータ返却がなくなり、エラー時の原因究明やメンテナンス性向上につながる。

それは多分、必要ない (YAGNI: You Ain't Gonna Need It)

YAGNIを簡単に説明すると、

  • 必要になりそうなコードを書かない
  • 必要になったら書く
  • 必要だと思ったものは案外使われない

と、言う意味らしいです。(知らなかった)

使うかどうかわからないものを書いてパフォーマンスの影響が出たり、リスクが増す可能性があるなら必要最低限の列を指定しようと言うこと。

まとめ

必要な列だけを指定するようにしよう

参考文献

SQLアンチパターン

参考文献.jpg

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?