hironomiu's Blog

こそっと書いていきます。twitter_id:hironomiu

今年も振り返ってみる!

このエントリーは VOYAGE GROUP エンジニアブログ : Advent Calendar 2013の23日目の記事です。

今年もこの季節になりましたね。去年のエントリー「一年の振り返り - hironomiuの日記」から丸1年振りのエントリーです。(あっという間で早いですね!)

今年も去年と同様に前半は@hironomiuの視点で2013エンジニアインターンの取組みについての振り返りを行い、後半は簡単なtipsですがSQL初学者向けのtipsをエントリーしたいと思います。(イヴイヴ感ゼロですね!)

インターン

夏のTreasure2013 、冬のSunrise2013 ともにメイン講師として初日から最終日までフル参戦となりました。両インターンともに成長意欲の高い学生が多くこちらの方が沢山刺激され成長させて貰えたのではと思っています。

Treasure2013

プログラミングによるサービス開発が主体のインターンですが裏ではイマドキ個人開発環境ってあるよね!と言うことでVirtualBox + Vagrant + Puppet + ServerSpecでのインターン生が持ち込んだPCに対してローカルでの個人開発環境の提供や本番環境を直接触るのではなく開発環境(今回は個人開発環境)からgithub + Jenkinsでのデプロイ連携で本番にアップするようなフローも経験して欲しいよねと環境や運用についても限られた時間の中モダンと言うキーワードを意識した意欲的な取り組みも行えたインターンでした。

インターン中の雰囲気については以下のブログを見て頂けると幸いです。

VOYAGE GROUP エンジニアブログ : 圧倒的な成長を目指す「Treasure2013」(前編改めプロローグ)
VOYAGE GROUP エンジニアブログ : 圧倒的な成長を目指す「Treasure2013」(前編)
VOYAGE GROUP エンジニアブログ : 圧倒的な成長を目指す「Treasure2013」(後編)

Sunrise2013

今年は技術的なコンセプトデザイン、そこから講師としての講義資料の作成、課題(事前、中間、最終)、実技用の環境構築、モックアプリの準備と全てを行った事もあり一大プロジェクトとなりました。Sunrise2013は大規模サービスを運営していく上での抽象度が若干高いサービス設計技術にフォーカスを当てています。そのため座学、実技を含めた講義の内容やアプリのモックなどについてもできるだけ個別な技術にフォーカスが当たらないように気をつけながら詳細を詰めていきました。*1

インターン中の雰囲気については以下のブログを見て頂けると幸いです。

VOYAGE GROUP エンジニアブログ : 100万人が使うWebサービスを創造せよ!!大規模サービス構築プログラム「Sunrise2013」

SQL tips

初学者向けなtipsですが社内ではたまに触れるtipsでしたので今回はそれを記載したいと思います。良く初学者の方で範囲検索の際にbetweenを使うべきなのかどのような等号の組み合わせを用いるべきなのかコーディングのお作法に近い質問を受けたりSQL作成時に苦慮が感じたりすることがあります。SQLを実行する際に実行計画について全く無視した解説は乱暴かもしれませんがあえて今回は実行計画には触れずtipsを記載したいと思います。

とある1日分のデータを取得する

例えば以下のようなレコードがあり12月23日分のレコード全てを取得したいとします。

mysql> select * from hoge;
+----+---------------------+
| id | created_at |
+----+---------------------+
| 1 | 2013-12-22 00:00:00 |
| 2 | 2013-12-22 23:59:59 |
| 3 | 2013-12-23 00:00:00 |
| 4 | 2013-12-23 12:00:00 |
| 5 | 2013-12-23 23:59:59 |
| 6 | 2013-12-24 00:00:00 |
+----+---------------------+
6 rows in set (0.00 sec)

パターン1 betweenでの書き方

mysql> select * from hoge where created_at between '2013-12-23' and '2013-12-24';
+----+---------------------+
| id | created_at |
+----+---------------------+
| 3 | 2013-12-23 00:00:00 |
| 4 | 2013-12-23 12:00:00 |
| 5 | 2013-12-23 23:59:59 |
| 6 | 2013-12-24 00:00:00 |
+----+---------------------+
4 rows in set (0.00 sec)

当然ですが上記では「| 6 | 2013-12-24 00:00:00 |」まで取得してしまいます。これでは仕様を満たせていませんね。

mysql> select * from hoge where created_at between '2013-12-23' and '2013-12-23 23:59:59';
+----+---------------------+
| id | created_at |
+----+---------------------+
| 3 | 2013-12-23 00:00:00 |
| 4 | 2013-12-23 12:00:00 |
| 5 | 2013-12-23 23:59:59 |
+----+---------------------+
3 rows in set (0.00 sec)

なんとか仕様を満たせました。ただ「'2013-12-23 23:59:59'」のようにデータ型を踏まえた境界値となる値を指定しないといけなそうですね。

パターン2 対義(<= >= | < >)となる等号を組み合わせる書き方

mysql> select * from hoge where created_at >= '2013-12-23' and created_at <='2013-12-23 23:59:59';
+----+---------------------+
| id | created_at |
+----+---------------------+
| 3 | 2013-12-23 00:00:00 |
| 4 | 2013-12-23 12:00:00 |
| 5 | 2013-12-23 23:59:59 |
+----+---------------------+
3 rows in set (0.00 sec)

どうもこの場合も「'2013-12-23 23:59:59'」のようにデータ型を踏まえた境界値となる値を指定しないといけなそうですね。

パターン3 個人的にオヌヌメな書き方

mysql> select * from hoge where created_at >= '2013-12-23' and created_at < '2013-12-24';
+----+---------------------+
| id | created_at |
+----+---------------------+
| 3 | 2013-12-23 00:00:00 |
| 4 | 2013-12-23 12:00:00 |
| 5 | 2013-12-23 23:59:59 |
+----+---------------------+
3 rows in set (0.00 sec)

上記はいかがでしょう?慣れの問題もありますがSQLの可読性も高くなった気がします。そして日付型の特徴である時刻を指定しない場合「00:00:00」に丸めることを利用し境界値についての敷居が低くなりました。

今回はMySQLinnodb)で例を作成しましたが大体のRDBMSでは日付型について日付を指定した際に時刻を省略した場合、時刻については「00:00:00」に丸める特徴は共通しているためRDBMSごとに日付型で持つ時刻の精度(時分秒〜ミリ秒...etc)について考慮することが不要となり他のRDBMSへの移植性も高くなります。*2

今回は範囲検索の中でも引っ掛かりやすい日付型でtipsを記載しましたが、日付型に限らず条件句での範囲指定の際にbetweenを必ず使用する必要はありませんし等号に関しても可読性を考慮して柔軟に組み合わせる事が大事ではないかと自分は考えています。逆に言うとSQLは柔軟な記述が出来るので日付型に限らず型による特性を理解し柔軟な記述をすることで可読性、移植性が高く意図した結果セットが取得できるSQLになるのでは?と考えています。

自分のエントリーはここまでにしたいと思います。

最終日の明日は圧倒的に事業を牽引している@suzu_vです。最終日にふさわしい素晴らしいエントリーを期待しましょう!!

それでは良いクリスマスを!!

*1:余談ですが裏では講義用にクラウド上にて約30台のサーバを用意しましたがgithub + puppetを主軸にミドルウェアパッケージのセットアップ、DBデータのセットアップ、モックアプリのデプロイ、動作検証までを、まだまだ改善の余地がありますが、ある程度自動化でき構築作業の工数を大きく下げ、他の作業に時間を割けた事は個人的には手応え感が大きかったインターンとなりました。

*2:当然ですがRDBMSごとに文字列を日付型として暗黙的にキャストすると等で認識するフォーマット等の考慮は必要ですね。