データベース固有の関数の使用を避けるべき理由

こんにちは、しょーやんです。

私はエンジニアとして12年目で、現在はエンジニアチームのリーダーとしてWebアプリケーションのシステムを開発しています。キャリアとしては、SIerで1年、ベンチャー企業で3年、300人程度の企業で5年、現在は6000人規模の会社でエンジニアとして働いています。

前提として、ここで話すことはアプリケーション設計に関する話しです。データベースの関数自体の使用を否定しているわけではありません。データベース固有の関数を使う前に少し考えてみましょうという話しです。まずは、データベース固有の関数を使うリスクについて説明します。

データベース固有の関数を使うリスク

データベースには固有の関数が用意されています。MySQLだとDATE_FORMATやNOW、SUMといったような関数です。これらを利用するのは便利ですが、安易な利用はおすすめしません。相応の理由がない限りは避けるべきです。理由は、データベース固有の関数を利用すると移植性が失われてしまうからです。

多くの人はデータベースを変更することはほとんどないだろうと考えます。本当にそうでしょうか。

例えば、開発環境ではSQLite、プロダクション環境ではMySQLを使うということは特段珍しいことではありません。
トランザクション境界を分離できないようなインテグレーションテストを実行するときはどうでしょうか。

ユーザーの情報を取得するAPIのインテグレーションテストがあるとします。このテストをクリアするためには、事前にユーザーのデータをデータベースに登録しておくことが必要です。そうでなければユーザーのデータを検証することができません。
テスト用のデータベースを共有で利用していた場合、一時的に作成されたテストデータが他のテストに影響するようになるでしょう。この問題は複数のテストが同時に実行されるようなCI環境になると顕著に現れます。解決策の1つとしてプロダクション環境と同じデータベースが含まれたイメージを作成するという手がありますが、複雑なイメージファイルを作成することは、なるべくなら避けたいところです。

データベースはドアノブである

ロバート・C・マーティンは著書「Clean Architecture」で、データベースはあくまで道具の1つであり、アーキテクチャの中心になるものではないと言っています。データベースは家のドアノブのようなものであり、アーキテクチャ的にはどうでもよいのです。ドアノブに家の設計を合わせることはしないでしょう。データベースがドアノブのようなものであれば、データベースに依存しないようにアプリケーションを実装するのは当然のことのように思えます。

RailsやSpringのような現在のフレームワークは、データベースを抽象化して扱えるような仕組みを提供しています。多くの場合、それはORMとして提供されており、利用するドライバーの設定を変更するだけでデータベースを変更することが可能です。

アプリケーション設計の側面から考えると、データベース固有の関数は避けるべきです。データベース固有の関数を利用する必要が場合は、基本的なCRUDで同じことができないかを検討しましょう。さもなければ、たった1つのデータベース固有の関数のせいでアプリケーションの移植性は失われてしまいます。

原則としてアプリケーション側で対応する

多くのアプリケーションは基本的なCRUDで構築することが可能です。少しの手間を省くためにデータベース固有の関数(例えばMySQLのREPLACE)を利用することはデメリットの方が大きくなる可能性があります。よく見られるアンチパターンはNOWの多様です。時刻はアプリケーション側で取得できます。アプリケーション側で対応できるものはアプリケーションの機能で対応しましょう。

データベース固有の機能に頼った方がいい場合

データベース固有の機能に頼った方がいい場合も存在します。例えば、位置情報を扱うような場合です。位置情報を扱う場合、PostgreSQLの拡張であるPostGISを利用した方が少ない労力で実装することができるでしょう。このように明確なアドバンテージがある場合はデータベース固有の機能を利用しない理由はありません。

手軽にスプラトゥーンをYouTubeで配信する

私はYouTubeやOPENREC.tvでよくスプラトゥーンの配信を視聴しているのですが、みているだけでなく自分もやってみたいと思ったのでYouTubeで配信をはじめてみました。この記事では、YouTubeでゲーム動画を配信する方法を紹介します。

配信の手順

配信の手順としては次の通りです。

  1. キャプチャボードを使ってゲームの動画と音声を外付けの記録媒体に保存
  2. 記録媒体に保存した動画をPCの編集ソフトを使って編集する(アフレコをしたり、不要な部分をカットしたり、音量の調整をする)
  3. 編集した動画をYouTubeにアップロードする

配信に必要な機材

  • キャプチャボード
    • ゲームの動画と音声をキャプチャするのに必要です
  • 記録媒体
    • USBメモリや外付けHDDなど。PCに保存する場合は不要です
  • PC
    • 動画の編集に必要です。私はMacBook Air(メモリは4GB)を使っています
  • マイク
    • 実況を録音するためのマイクです

キャプチャボードを用意する

ゲームの動画と音声を録画するにはキャプチャボードが必要です。キャプチャボードには様々な種類があり、どれを使ったらいいのかよくわからなくなると思います(私がそうでした)。私のおすすめのキャプチャボードはI-O DATA HDMI キャプチャーボード GV-HDRECです。

このキャプチャボードは1万円程度と手頃な値段で操作方法も簡単です。最初の1台としておすすめできます。ただし、PCとの接続はできないので、リアルタイム配信には使えません。

記録媒体を用意する

私は32GBのUSBメモリを使っています。スマートフォンに接続できるタイプがおすすめです。録画した動画をスマートフォンで観たり、不要な動画を削除したりできます。

32GBで2時間程度の録画ができます(記録形式によって時間は変わります)。32GBだとこまめにデータを消す必要があるので、もう少し大きな容量がよいかもしれません。

動画の編集

画像の編集はiMovieを使っています。簡単な編集であればiMovieで十分です。YouTubeへのアップロード機能もついており、この機能を使ってYouTubeにアップロードしています。iMovieの操作方法についてはドキュメントをご覧ください。

アフレコに使うマイクはアップルの純正イヤホンのマイクを使ってます。

おわりに

このような感じで、特に難しいことをせずに動画配信ができてしまいます。今後もスプラトゥーンの動画を配信していくので、ぜひチャンネル登録お願いします!

シェルスクリプトで別プロセスの終了ステータスを取得する

シェルスクリプトで別プロセスの終了ステータスを取得するTipを紹介します。

ユースケース

時間のかかる処理などを並列で行い、その実行結果(終了ステータス)を取得したい。

サンプルコード

Bashのサンプルコードです。スクリプトに解説を記入しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#!/bin/bash

command1() {
echo "executing commnad1"
sleep 3
}

command2() {
echo "executing commnad2"
sleep 3
# エラーとして終了させる
exit 1
}

echo "start"

# バックグラウンドで実行
command1 &
# $!で直前に実行されたコマンドのプロセスIDを取得し、変数に保存している
pid1=$!

command2 &
pid2=$!

# waitは指定されたプロセスIDの処理が終わるまで待つ
wait $pid1

# $?でwaitで指定しているプロセスの終了ステータスを取得することができる
if [ $? != 0 ]; then
echo "command1 error"
else
echo "commnad1 success"
fi

wait $pid2
if [ $? != 0 ]; then
echo "command2 error"
else
echo "command2 success"
fi

echo "end"

gistにもコードをアップしています。

shellの学習は次の書籍を1冊やっておけば大丈夫です。

RubyでのWebアプリケーション開発はSinatraから入りRailsに行く

私はソフトウェアエンジニアなのですが、プログラミング講師としても生徒さんにRubyを教えています。RubyでWebアプリケーションを作る場合、まず候補になるフレームワークはRuby on Railsですが、Railsは初学者には難しいと思います。プログラミング初学者にRailsを教えるということは、車の教習所でいきなりスポーツカーを運転させるようなものです。入門者には入門者に適した車があるのと同様にプログラミングにもそのようなものがあります。

では、最初は何がいいかというと、Sinatraがよいと思います。そういうわけで、Sinatraを使ったWebアプリケーションのサンプルを探してみたのですが、よいものが見つかりませんでした。ないなら作ってしまえというわけで作りました。

今回作成したのはシンプルなメモアプリケーションでフォームに入力した値をメモとして保存することができます。作成したメモの一覧表示、詳細表示、編集機能、削除機能を実装しています。基本的なCRUD操作を備えており、RESTについても学ぶことができるようになっています。

わかりやすいようにディレクトリをわけています。initialディレクトリは最初からフルスクラッチで作る場合のディレクトリです。step1はメモの作成とメモの表示機能を実装しています。step2はstep1の機能にメモの削除とメモの編集機能を追加しています。

実装にあたっては、できるだけRubyの標準ライブラリを使うようにしました。理由は長い年月において最も安定的に使えるのはRubyの標準ライブラリであることからです。サードパーティのライブラリは便利ですが、Rubyのバージョンアップによる互換性の問題などを含んでいます。将来的にも安定して動作させることを考慮すると標準ライブラリで実現できる機能であれば標準ライブラリを選択するのは良い選択肢だと思います。

また、データベース(正確にはRDBMS)はややこしいので使っていません。もう少し丁寧に説明すると、今回のアプリケーションはプログラミング初学者の学習に適しているアプリケーションをシンプルな実装(環境も含めて)で作るということを目的として作ったので、その点でRDBMSは適していません。では、どうやってメモを永続的に保持するのかというと、ファイルとして保持しています。この機能の実装には、Rubyの標準ライブラリであるpstoreを利用しました。pstoreとはオブジェクトをそのままファイルとして保存するライブラリです。メモアプリケーションの機能を実現するなら、これで十分なわけです。

Webアプリケーションはリクエストとパラメーター(必要であれば)をアプリケーションサーバーに送信し、ルーティング設定に従ってそのリクエストを処理します。そして、レスポンスを返します。この流れを理解することがはじめの1歩です。この流れが理解できていない状態でRailsを使うのは早すぎるように思いますし、データベースの用意やらマイグレーションやらは確実に最初の壁となってプログラミング初学者に立ちはだかるでしょう。

そのようなややこしいことは置いておいて、まずは小さな動くアプリケーションを作りましょう。Sinatraであればターミナルに数コマンドを打つだけでアプリケーションを起動できます。自分で全てのコードを書いても数時間程度で書くことができます。コードのほとんどは標準のRubyのライブラリを使用しているため、とてもシンプルです。

ここまではRailsについて散々けなしていますが、誤解のないように断っておくと、本格的なWebアプリケーションを作るのであればRailsがいいです。習得に数ヶ月はかかるでしょうが、多くの機能を少ないコードで実装できてしまうRailsの生産性の高さは、それだけの時間をかける価値があります。しかし、プログラミング初学者がいきなりRailsから入るのは難しいのではと思います。RubyでのWebアプリケーション開発は、まずはSinatraから入りそこからRailsに行くのがよいというのが私の考えです。

Developers Summit 2018 FUKUOKAに登壇します

2018年9月7日にアクロス福岡で開催される Developers Summit 2018 FUKUOKA(デブサミ福岡)に登壇します。
明日はどのような話しから入ろうかがまだ決まっていなくて、どうしようかと考えています。

発表内容は0からはじまった開発チームが、どのようにチームとしてまとまっていき、アプリケーション開発を成功させることができたかという事例の紹介となります。

デブサミ福岡のような大きなイベントに登壇するのは今回が初めてなので、うまくできるか不安ではありますが、精一杯やりたいと思っています。もし、当日会場に来られる方がいれば是非、お声がけください。