Date:  Wed, 15 Sep 2010 17:57:04 +0900
Subject:  【オブジェクト倶楽部: 2010-35号】
X-Mail-Count: 00353

       ┏━━━━━━━━━━━━━━━━━━━━━━━━━━■
       ┃                         ■┃
      ●┃● ● オ ブ ジ ェ ク ト 倶 楽 部   ■ ┃
       ┃                       ■  ┃
       ┗━━━━━━━━━━━━━━━━━━━━━━■━━━┛
                          No.343 2010/09/15

■ I N D E X
┃
┣【アジャイル】アジャイル・プラクティスの見つけ方 [18]
┃              〜しばらく会っていないエンジニアの友人に話を聞く〜
┣【プログラミング】ドキュメント指向データベースMongoDB [6]
┗ 編集後記

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ■━
■
┣【アジャイル】アジャイル・プラクティスの見つけ方 [18]
┗              〜しばらく会っていないエンジニアの友人に話を聞く〜

こんにちは。こんぴろです。みなさんは夏休みをとられましたか?夏休みなど
の長期休暇には故郷に戻り、旧友と会う方も多いと思います。最近は仕事の関
係で8月のお盆の時期に夏休みをとらず、9月にずらす方も増えています。もし
これから夏休みを取られる方は、ぜひ普段あまり会えない友人と会う事をお勧
めします。というのも、旧友と会うとおのずと普段の自分をふりかえる機会に
なることが多いからです。

私も先日学生時代の友人で、エンジニアとして日々働いているA氏と会いました。
A氏も日々の仕事の中で工夫をしている事も多いのですが、悩みを抱えていまし
た。そういった悩みを聞いていると、日々の仕事の中では忙しさに流され、忘
れていた問題に再び気づく事があります。

例えばA氏のチームではデイリービルドを実践しているのですが、デイリーテス
ト中に実行されるユニットテストに時間がかかり過ぎ、1回のビルドに12時間以
上かかるそうです。A氏のチームでは「単体テスト」と呼んでいても、全ての実
装が統合された状態のテストが書かれていたため、テストの実行に時間がかか
りすぎていたのです。「これって単体テストって呼べないよね。」とA氏は嘆い
ていました。

こういったテストに時間がかかりすぎる問題は、テストコードを書くチームか
らよく聞きます。私のチームでも状況はそんなに大きくは変わりません。時間
がかかりすぎるテストは多くないのですが、結果がランダムになってしまって
いるテストや、実行する環境によって結果が変わるテスト等があります。そう
いったテストは、ふと結果が成功になる事があるので、「大丈夫」としてしま
う事も多いでしょう。しかし、もしかするとそういうテストの中に、実行状況
によって結果が変わる、厄介なバグが潜んでいるかもしれないのです。ですの
で、そういうテストは単純に失敗するテストよりもより高い優先度で取り組ん
だ方が良いでしょう。

私もこうして改めてふりかえってみて問題を見つけられたのですが、通常行っ
ているふりかえりはだんだんとマンネリになってしまい、問題があっても、議
論しづらくなってしまう事もあるでしょう。また、前回紹介した分散勉強会で
共有しているので、大丈夫、といった過信のようなものを生んでしまう事もあ
ります。
私とは異なった環境で仕事をする友人の話を聞き、改めて自分の環境をふりか
えり感じた事は、次の一歩につながっている気がするのです。

今回はパターンとしてではなく、パターンにする前の私の気づきをお伝えしま
した。次回もお楽しみに。(こんぴろ)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ■━
■
┗【プログラミング】ドキュメント指向データベースMongoDB [6]

こんにちは、ursmです。
今回は少し特殊なカタチのアップデートについてご紹介します。

● Upsert
条件に該当するドキュメントが存在するならアップデート、存在しないならイ
ンサートする機能です。Update+InsertでUpsertというわけですね。MySQLの
"INSERT ... ON DUPLICATE KEYUPDATE"構文に相当するものです。

通常、updateコマンドは更新対象のドキュメントがなければ何もしません。

> db.users.count()
0
> db.users.update({name: 'ursm'}, {$inc: {login_count: 1}})
> db.users.count()
0

updateコマンドの第三引数にtrueを指定するとUpsertになります。

> db.users.update({name: 'ursm'}, {$inc: {login_count: 1}}, true)
> db.users.count()
1
> db.users.findOne()
{
 "_id" : ObjectId("4c8f33cc5ffedb18058f732a"),
 "login_count" : 1,
 "name" : "ursm"
}

さらに同じコマンドを実行すると、先程作成したドキュメントを更新します。

> db.users.update({name: 'ursm'}, {$inc: {login_count: 1}}, true)
> db.users.count()
1
> db.users.findOne()
{
 "_id" : ObjectId("4c8f33cc5ffedb18058f732a"),
 "login_count" : 2,
 "name" : "ursm"
}

Upsertを使うと、ドキュメントの存在確認と作成/更新をアトミックに行えるた
め、データの不整合を避けつつパフォーマンスを高めることができます。特に
バッチ処理で大量のデータをインポートするような場合に便利でしょう。

● Find and Modify
ドキュメントの中にユニークなカウンタ値を保存するとしましょう。値を読み
出す前か後でアトミックにインクリメントすれば良さそうなものですが・・・。

> db.serials.update({_id: 'num_1'}, {$inc: {value: 1}}, true)
> db.serials.find()
{ "_id" : "num_1", "value" : 1 }
> db.serials.update({_id: 'num_1'}, {$inc: {value: 1}}, true)
> db.serials.find()
{ "_id" : "num_1", "value" : 2 }

この処理を複数のクライアントが同時に行った場合、重複した値を読み出して
しまう可能性があります。

クライアント1: > db.serials.update({_id: 'num_1'}, {$inc: {value: 1}}, true)
クライアント2: > db.serials.update({_id: 'num_1'}, {$inc: {value: 1}}, true)
クライアント1: > db.serials.find()
クライアント2: > db.serials.find() #=> 値が重複する

こんな場面で使えるのがfindAndModifyコマンドです。これはドキュメントの更
新と取得をアトミックに行うものです。先程の例を書き換えてみましょう。

(行頭の"..."は前の行から続いていることを表します)

> db.serials.findAndModify({
... query: {_id: 'num_1'},
... update: {$inc: {value: 1}},
... upsert: true,
... new: true})
{ "_id" : "num_1", "value" : 3 }

findAndModify()は引数として1つのオブジェクトを受け取ります。
query, update,upsertはupdate()と同じなので説明は不要ですね。newがtrueだ
と更新後の、falseだと更新前のドキュメントが戻り値になります。

● まとめ
UpsertとFind and Modifyをご紹介しました。いずれもトランザクションのない
MongoDBにおいてデータの一貫性を保つためには必須となる機能です。(id:ursm)

● 参考
 * http://www.mongodb.org/display/DOCS/Updating
 * http://www.mongodb.org/display/DOCS/findandmodify+Command

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━--■--●--■
■
┗編集後記

こんにちは、編集人のナガタユウコです。先週石垣島に行ってきました!那覇
には何度か行ったことがあるのですが、石垣島は初めてで、そののんびりとし
た雰囲気と、なにより自然の美しさに感動しました。絶対にまた来る!と決め
て東京に戻ってくると、慣れ親しんだ日常と便利さに感動・・・。土地にはそ
の土地ごとの魅力があるものだな、と実感しました。もっともっといろんな所
を訪れて、たくさんの魅力に出会いたいと思いました☆ (ナガタユウコ)

*** オブラブスタッフ自己紹介 ***
No.24 西村(nawoto)
( @nawoto, http://d.hatena.ne.jp/nawoto/ )
どうも、西村(nawoto)です。私のオブジェクト倶楽部としての仕事としては、
主にイベントのスタッフと、ときたま自分の好きなキーワードをカレンダーや
メルマガに書かせてもらっています。最近では、カレンダーに書いたScrum特集
を3ヶ月連続で紹介させてもらっています。
しかし、年々若い人の台頭によって、活動範囲が狭くなってきているように感
じています(笑)。しかし、これは悪い事ではなく、最近のイベントでの若人ト
ラックのように、オブラブには色んな人の登竜門的な場としての魅力がありま
す。今でこそ色んな勉強会やイベントはありますが、僕はオブラブのこういう
一面が非常に好きです。
僕も最近はオブジェクト倶楽部以外で発表する機会も増えてきましたが、人前
でのプレゼンデビューは2007年のオブジェクト倶楽部クリスマスイベントでし
た。今でもその時の思いや色んな人からいただいたフィードバックは大切にし
ています。
これからもオブラブを登竜門に色んな人が活躍できるように若いスタッフや参
加者の方を支えられるよう頑張っていきますので、よろしくお願い致します。
(nawoto)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━--■--●--■
● ご意見、ご感想は         ⇒このメールに返信ください
〇 配信中止、アドレス変更は ⇒/community/object_ml/help/
〇 免責事項、過去の記事は   ⇒/community/object_ml/
■ 発行:オブジェクト倶楽部 ⇒http://ObjectClub.jp/
Copyright (c)2010 オブジェクト倶楽部. All Rights Reserved.
powered by Eiwa System Management, Inc.