SHOYAN BLOG

I am a pragmatic programmer.

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

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

私はエンジニアとして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を利用した方が少ない労力で実装することができるでしょう。このように明確なアドバンテージがある場合はデータベース固有の機能を利用しない理由はありません。

相談ではなく明確な基準を決めよう

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

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

度々「相談」という言葉が耳に入ってきます。この「相談」という言葉について耳にするたびに「基準を作ればいいのに」と思います。今回は「相談」と「基準」について考えていきたいと思います。

はじめに私の周りで使われている「相談」について説明します。「相談」とは次のような意味で使われています。

なんらかの判断を行わないといけないとき、その判断の観点を他者に伺う、もしくはその判断が正しいのどうかを他者に伺う行為。

相談の問題点

私は「相談」という言葉があまり好きではありません。それは、相談が引き起こすふるまいには次の問題点があるからです。

  • スピードが遅い
  • 権力者の考えによって判断が異なる
  • 自身で意思決定ができない

スピードが遅い

自分以外の誰かに相談するということは、次のようなタスクが必要になってきます。

  • 忙しい上司を捕まえる
  • 関係者とMTGの時間を設定する
  • 説明する資料を用意する

これらは本質的な仕事ではなく、仕事のスピードを遅くするだけのタスクにすぎません。

権力者の考えによって判断が異なる

多くの場合、なんらかの権利・権力を持っている他者に対して相談を行うことになると思います(なんらかの権利・権力を持っているので権力者と呼ぶことにします)。例えば、ある権力者はAと言いますが、他の権力者に聞いてみるとBと言います。このように権力者によって回答が異なる場合、現場は混乱します。

自身で意思決定ができない

自身で意思決定ができない環境でプロフェッショナルとして仕事を行うことは困難です。

相談ではなく明確な基準を決める

このように相談にはいくつかの問題があります。相談の問題が見えてきたところで、「基準」について説明します。

「基準」とは何かの判断を行うときの指標となるものです。例えば、火事が起こったら119番に電話しますし、泥棒に入られた時は110番に電話しますよね。誰も迷うことはないと思います。これは、明確な基準が定められているからですね。

私は相談ではなく明確な基準を決めるのがよいと考えています。それは、次のようなメリットがあるからです。

明確な基準を決めるメリット

誰が判断しても同じ

明確な基準があれば上長であろうが、あなたであろうが、誰が判断しても同じです。基準の前で立場は関係ありません。

その場で当事者が判断することができる

誰が判断しても同じ結果になるわけですから、いちいち誰かに相談する必要はありません。忙しい上司を捕まえたり、関係者とMTGの時間を設定したり、説明する資料を作成する必要もありません。今、この場であなたが決めればいいのです。

相談と明確な基準の比較

相談と明確な基準の比較をするために、2つの組織を例として考えてみます。

1つ目の組織では最終的な判断は上長に相談する必要があります。意思決定をするのに上長とのアポイントメントや説明資料が必要です。意思決定を行うためには1日程度かかるかもしれません。

2つ目の組織は明確な基準があり、その基準をもとに問題に直面している当人が判断を行います。明確な基準があるので、その問題に直面している人がその場で決めることができます。

この2つの組織を比較した場合、生産性が高いのは明らかに基準が明確な組織です。このように相談と基準のどちらの戦略をとるかで、生産的な面においての差がみてとれます。

考えてみよう

  • あなたの周りではどのような時に相談が必要でしょうか?
  • 相談が必要なことを明確な基準に変えることはできないでしょうか?

手軽にスプラトゥーンを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に行くのがよいというのが私の考えです。