銀行員からのRailsエンジニア

銀行員からのRailsエンジニア

銀行員から転身したサービス作りが大好きなRailsエンジニアのブログです。個人で開発したサービスをいくつか運営しており、今も新しいサービスを開発しています。転職して日々感じていること、個人開発サービス運営のことなどを等身大で書いていきます。

【読書まとめ24】王道SEO対策 実践講座 

読書まとめの第24弾です。

今回は、成果を出し続けるための 王道SEO対策 実践講座 を読みました。

SEO対策の基本について解説している本で、会社のSEOに強い方に教えていただき読みました。

会社のサービスをはじめ、自分のサービスやブログにもすぐに実践できる内容だったので、忘れないように要点をまとめます。

すぐに読めると思うので、SEOの対策の基本について興味がある方は是非ご覧ください。

成果を出し続けるための 王道SEO対策 実践講座

成果を出し続けるための 王道SEO対策 実践講座

 

SEO対策について考えている男性

SEO対策のポイント

  • Webサイトの更新頻度は、SEO対策において重要な要素の一つとなる
  • パンくずリストを利用することが、最適なリンク構成を実現するための最も単純で基本的な方法
  • ドメインやURLは、一度決定したら対象ページが存在している限り変更しない
  • alt属性は画像が表示されない場合にどのような画像を表示したかったかを利用者に伝える手段になるとともに、目の不自由な方が画像の内容を知るための手助けになるので、通常は見えなくても利用者にとって非常に重要な要素となる。適切に利用すればコンテンツの評価を上げる要素となる
  • オリジナリティがコンテンツの価値になる。テンプレートや画像を提供するECサイトは、画像や価格が異なる程度で、ほとんど内容が同じページが量産されてしまうことがある。こうしたページが重複コンテンツと判断されたり、テキストの要素が少ない価値の低いコンテンツと判断されたりして、ペナルティを課される可能性もある。そのため、画像を撮影した際のデータや商品の仕様などをできるだけ記載して情報を増やしたり、コメント機能で利用者のコメントを集めたりして、それぞれのページが異なる内容を提供できるようにするべき
  • アクションにつながるキーワードを含めるとその後の行動に結びつきやすい。具体的には、「SEO対策 相場」や「デジカメ 激安」などの購入したいという意思や、「デジカメ 修理」や「名刺 即日」などのすぐ必要という緊急性を含んでいるワードである

具体的な指針

  • titleについて
    • 全角30文字以内
    • 対象ページで狙うすべてのキーワードを入れる
    • キーワードの重複は避ける
    • 意味区切りは「|」「-」「:」のどれかで区切る
  • descriptionについて
    • 全角100文字以内
    • 対象ページで狙うすべてのキーワードを入れる
    • キーワードの重複は避ける
    • すべてのページでdescriptionが同じだとマイナス評価につながる
  • キーワードを乱用すると、ペナルティの対象となることがある。具体的な利用の目安は以下の通り
    • 見出し:h1から順に利用し、h1が利用できるのはまとまりにつき1つ
    • strong要素:利用は1ページにつき数回程度で、同じ語句には使わない
  • キーワードの出現率の参考値は以下の通り。無料ツールを使って調べることができる
    • 1番目に対策したいキーワード:適正出現率 5〜7%
    • 2番目:4〜5%
    • 3番目:3〜4%

ツール

  • Search Consoleは、Googleの検索結果でのWebサイトのパフォーマンスを監視、管理できるサービス。WebサイトがGoogleにどのように認識されているか確認できるので、検索結果でのパフォーマンスを最適化するのに役立つ
  • Webサイトの運営開始直後で、なかなかクローラが回って来ず、インデックス化までに時間がかかる場合は、Search ConsoleやBing WebマスターツールからURLを指定してクローラの巡回を催促することができる
  • Search ConsoleでXMLサイトマップを登録すると、より早くWebサイトの更新情報を検索エンジンに伝えられるので、クローラが回ってくるまでの時間が短くなるとともに、抜け漏れなく情報を収集してもらえるようになる
  • 内部リンクはWebサイト内に置ける相対的重要度の指標として利用されるので、強化したいページにリンクを集中させられていない場合は、設計通りの成果を出しづらい
  • Search Consoleの「HTMLの改善」を利用することで、HTMLの不足要素や重複を一度にチェックできる

おわりに

ここまで読んでいただきありがとうございます。

特に、具体的な指針の項目は今日から使えるものばかりだったので、すぐに実践していこうと思います。 

この記事で紹介しきれないくらい、多くのSEOについてのことが解説されていたので、SEO対策について網羅的に理解したい方におすすめです。

成果を出し続けるための 王道SEO対策 実践講座

成果を出し続けるための 王道SEO対策 実践講座

 

次はWebの速度改善についての本を読んでみようと思います。

AMP Conf 2019に行ってきました!印象に残ったセッションなどまとめ

4/17(水)、18(木)に、六本木ヒルズで行われたAMP Conf 2019に参加してきました!

参加する前は、AMPについてほとんど何も知らない状態だったのですが、2日間でAMPすげー!となったので、印象に残ったセッションなどについて書いてみます。

AMPについて知らなかった方最近のAMPについて興味がある方の参考になれば嬉しいです。f:id:ysk_pro:20190421145044j:plain

AMPとは

AMP(Accelerated Mobile Pages)は、モバイルページを高速で表示させる技術で、2015/10にGoogleTwitterオープンソースプロジェクトとしてスタートしました。

スマホGoogle検索した時に、こちらの画像のようにカミナリマーク(⚡️)がついているのがAMP対応ページで、クリックしてみると爆速で表示されるのが分かります。ほんとにビックリするくらい爆速です。

f:id:ysk_pro:20190421131912p:plain

f:id:ysk_pro:20190423155212g:plain

(こちらは「ラクマ スマブラ」と検索した結果で、1ページ目に表示されていました)

読み込めるJavaScriptや、CSSの容量に制限を設けることで読み込みにかかる時間を減らし、さらにGoogleがコンテンツをキャッシュしていることなどによって、このスピードを実現しています。

こちらのAMP Confのオープニング動画(4分くらい)が分かりやすく、そして面白くAMPについての概要を解説してくれているので是非ご覧ください。

youtu.be

(よくありがちな、会場への道中で色々説明していって、最後に本当に会場に登場するやつです 笑)

 

AMP Confとは

年に一回開催される、開発者の開発者による開発者のための AMP の技術祭典を、今年は東京で行います。(公式ページより) 

公式ページはこちらです(もちろんAMP対応しています)

2018年はオランダのアムステルダム、2017年はニューヨークで開催されており、懇親会で話を聞くと、このイベントのためにブラジルやカナダから来た人もいるような世界的なイベントです。

 

印象に残ったセッション

全てのセッションYouTubeこちらに公開されています(YouTubeの自動翻訳が使えるので英語が分からなくても安心!)

amp.dev live!

2人のGoogleのエンジニアが、30分でAMPページをライブコーディングするセッションです。

作ったAMPページの画像は以下で、次の機能を備えています。

  • 下タブでコンテンツを切り替えられる機能
  • 下スクロールでナビゲーションバーが隠れて、上スクロールで表示される機能
  • ツイートを15秒ごとに自動で取得する機能
  • 無限スクロール機能

f:id:ysk_pro:20190421134222p:plain
AMPページは、用意されているコンポーネントを組み合わせて作ることが多いようです。このライブコーディングを通じて、実装のイメージが湧いたのでとても良かったです。

そしてGoogleのエンジニアかっこいいなぁ。

youtu.be

 

AMP Stories: The Story so far

AMPでこんな感じのストーリー機能が実装できます。おしゃれ!

f:id:ysk_pro:20190421143207p:plain

また、検索結果にAMPストーリーを表示する専用の箇所を作ることを検討しているようなので、今のうちにAMPストーリーを作っておくといいかも。

f:id:ysk_pro:20190421143300p:plain 

簡単に綺麗なストーリーが作れるようなので、是非作ってみたい...!

youtu.be

 

AMP for Email: pushing the boundaries of email with AMP

Emailは基本的に、テキストかシンプルなhtmlで構成されていると思います。

しかし、AMP for Emailを使えばこのようにインタラクティブなコンテンツを提供することができます。

f:id:ysk_pro:20190421144059p:plain

↓これが分かりやすいです(セッション動画を該当箇所から再生するようにしています)

Email上で申し込みや購入までできたりするの、とてもいいですよね。

現在はGmailのみが対応しているそうですが、今後他のメールクライアントでも対応予定だそうです。

このセクションの中では実際の実装方法も詳しく解説されており、通常のAMPページ同様にシンプルに実装できそうだったので、試してみようと思っています。

youtu.be

 

懇親会

1日目の夜にパーティーがあり、参加者やGoogleの方などとお話しすることができました。

DJがいて、ご飯も美味しくて楽しかったー。

f:id:ysk_pro:20190421145023j:plain

f:id:ysk_pro:20190421145034j:plain

寿司!! 

 

おわりに

AMPについてほとんど何も知らない状態で参加しましたが、2日間を通じてAMPのファンになりました。

業務扱いで参加させてもらったので自社プロダクトのAMPページを改修するのはもちろん、個人で作るサービスでも使ってみようと思いました。

最初にも書きましたが、全セッションはYouTubeで公開されているので、気になった方は是非ご覧くださいー!

【技術書まとめ23】リーダブルコード

毎週1冊技術書を読んでブログでアウトプットすることが目標で今回が第23弾です。

今回は、リーダブルコード  を読みました。

もはや説明不要の名著ですが、良いコードを書くための原則を分かりやすく、そして簡潔に解説している本です。

200ページ程度でサクッと読めましたが、気づきがとても多かったです。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

 

f:id:ysk_pro:20190401065701p:plain

1章 理解しやすいコード

  • コードは「他の人が最短時間で理解できるように」書く
 

2章 名前に情報を詰め込む

  • tmpなどの汎用的な名前が単なる怠慢で使われていることも多い。いい名前が思いつかなかったらfooのような意味のない名前を使いたくなってしまうが、少しでも時間を使って名前を考える習慣をつけるようになればすぐに命名力は高まる
  • 抽象的な名前よりも具体的な名前を使う
  • 単位やセキュリティなどの重要な属性を名前に追加するのも有効(例 ミリ秒を表す変数名には、後ろに _ms をつけるなど
 

3章 誤解されない名前

  • 誤解される可能性がある名前をつけない。「他の意味と間違えられることはないだろうか」と自問自答する
  • 上下の限界値を決めるときは、max_ や min_ を前につけるとよい
  • ブール値に名前をつけるときは、それがブール値だとわかるように is や has などを使う
 

4章 美しさ

  • 複数のコードブロックで同じようなことをしていたら、ぱっと見て分かるようにシルエットも同じようなものにする
  • コードを縦に揃えて楽に読めるようにする
 

5章 コメントすべきことを知る

  • コメントの目的は、書き手の意図を読み手に伝えること
  • コードからすぐにわかることをコメントに書かない
  • コメントよりも自己文書化された適切な名前(関数名、変数名)をつけるべき
  • 優れたコメントは、コードを書いた考え(なぜコードが他のやり方ではなくこうなっているのかなど)を記録するためのもの
  • 定数を定義するときに、その定数が何をするのか、なぜその値を持っているかという背景をコメントするとわかりやすくなるケースが多い
  • 読み手の立場になって考え、質問されそうなこと、ハマりそうな罠についてコメントする
 

6章 コメントは正確で簡素に

  • 複数のものを指す可能性がある「それ」や「これ」などの代名詞を避ける
  • 入出力の実例をコメントに書いておくことは千の言葉に等しい
 

7章 制御フローを読みやすくする

  • ネストの深いコードは理解しにくい。ネストが深くなると、読み手は「精神的スタック」に条件をプッシュしなければならない
  • 「失敗ケース」をできるだけ早めに関数から返すことで、ネストを削除できることが多い
  • 比較を書くときには、変化する値を左に、より安定した値を右に配置する
  • If/elseのブロックは適切に並び替える。一般的には、肯定系・単純・目立つものを先に処理する
 

8章 巨大な式を分割する

  • 人間は一度に3〜4つの「もの」しか考えられないので、コードの式が大きくなれば、それだけ理解が難しくなる
  • 大きな式の値を保持する説明変数を導入すれば、巨大な式を分割でき、コードを文書化することができる
 

9章 変数と読みやすさ

  • 変数のスコープを縮めると読みやすくなる
  • 変数が絶えず変更され続けると現在値の判断が難しくなりコードが理解しにくくなるので、変数は一度だけ書き込むようにするとよい
 

10章 無関係の下位問題を抽出する

  • 以下のステップで無関係の下位問題を見つけて抽出する
    • 関数やコードブロックを見て「このコードの高レベルの問題は何か?」を自問する
    • コードの各行に対して「高レベルの目標に直接的に効果があるのか?あるいは、無関係の下位問題を解決しているのか?」を自問する
    • 無関係の下位問題を解決しているコードが相当量あるば、それらを抽出して別の関数にする
  • 関数は、小さく独立したものになっていれば、機能追加・エッジケースの処理などが楽にでき、読みやすくなる
  • プロジェクト固有のコードから汎用コードを分離する。ほとんどのコードは汎用化できる
 

11章 一度に1つのことを

  • 一度に1つのタスクをするためには、まずコードが行なっているタスクを全て列挙し、タスクをできるだけ異なる関数に分割するとよい
  • 最も大切なのは、プログラムが行なっていることを正確に説明すること
 

12章 コードに思いを込める

  • 誰かに複雑な考えを伝えるときには、細かいことまで話しすぎると相手を混乱させてしまう。自分よりも知識が少ない人が理解できるような「簡単な言葉」で説明する能力が大切。これには、自分の考えを凝縮して、最も大切な概念にすることが必要となる。これは誰かに理解してもらうだけでなく、自分の考えをより明確にすることにもなる
  • コードというのは、プログラムの動作を説明する最も大切な手段である。つまり、コードも簡単な言葉で書くべき。問題や設計をうまく説明できないのであれば、何かを見落としているか、詳細が明確になっていないということ。プログラム(あるいは自分の考え)を言葉にすることで明確な形になる
  • 以下のステップでコードを明確にすることができる
    • コードの動作を簡単な言葉で同僚にもわかるように説明する
    • その説明の中で使っているキーワードやフレーズに注目する
    • その説明に合わせてコードを書く
 

13章 短いコードを書く

  • 自分で書いたコードであれば、全ての行をテストして保守しなければいけない。ライブラリの利用や機能の削除をすることで、時間の節約をしたり、コードを簡潔に維持したりできる
  • プロジェクトが成長しても、コードをできるだけ小さく軽量に維持するために、以下のことをすべき
    • 汎用的なユーティリティコードを作って、重複コードを削除する
    • 未使用のコードや無用の機能を削除する
    • プロジェクトをサブプロジェクトに分割する
 

14章 テストと読みやすさ

  • 他のプログラマが安心してテストの追加や変更ができるように、テストコードは読みやすくするべき
  • 一般的な設計原則として、大切ではない詳細はユーザから隠し、大切な詳細は目立つようにする
  • テストの本質は「こういう状況と入力から、こういう振る舞いと出力を期待する」というレベルまで要約できる。そして、これらは1行でまとめられることが多い
  • テストの入力値は、コードを完全にテストする最も単純な組み合わせを選択する

 

おわりに

ここまで読んでいただきありがとうございます。 

本書の中では、イラスト・実際のコードを使って解説しており、とても分かりやすくて読んでいて楽しい本だったのでオススメです。 

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

 

早いもので、もう4月ですね。

次は何を読もうかなー。

来週も頑張ります!

【技術書まとめ22】Effective Ruby

毎週1冊技術書を読んでブログでアウトプットすることが目標で今回が第22弾です。

今回は、Effective Ruby  を読みました。

Rubyの効果的なコードの書き方について詳細に解説している本です。

知らなかった書き方も多く、明日から即実務で使えるとても有意義な技術書でした。

Effective Ruby

Effective Ruby

 

f:id:ysk_pro:20190325192504p:plain

第1章 Rubyに身体を慣らす

  • Rubyでは、falseとnilを除くすべての値が真である。多くの言語とは異なり、Rubyでは数値ゼロは真となる
  • falseとnilを区別しなければならないときは、nil?メソッドを使うか、falseを左被演算子とする”==”演算子を使う
  • すべての変数がnilかもしれないという前提でコードを書くようにする。適切であれば、to_s、to_iなどの変換メソッドを使ってnilオブジェクトを強制的に型変換する
  • 定数とは、先頭が大文字になっている識別子のことである。クラスやモジュールの名前も実際には定数である
  • 定数は書き換えられないようにfreezeすべき。定数が配列やハッシュなどのコレクションオブジェクトは、コレクションとその要素それぞれをfreezeする
  • コンパイル時に生成される警告は重要である。大多数は、Rubyが曖昧な構文を検出し、さまざまな解釈のなかから1つを選んで先に進んだときに生成される。Rubyの将来のバージョンが解釈方法を変え、プログラムの動作が突然変わってしまうことを避けるために、曖昧さは取り除いておくべき
 

第2章 クラス、オブジェクト、モジュール

  • クラスは、メソッドと定数の入れ物である。メソッドはインスタンスメソッドと呼ばれ、そのクラスのインスタンスとなっているすべてのオブジェクトの振る舞いを表現する。しかし、クラスはそれ自体もオブジェクトなので、クラス変数という変数の入れ物でもあり、クラスメソッドを持っている
  • Rubyは多重継承をサポートしていないが、includeメソッドでクラスにモジュールをミックスインすれば、多重継承と同じような効果が得られる
  • Includeメソッドを使ってモジュールをミックスインした時、Rubyは水面下で特異クラスを作ってインクルードしたクラスの上の階層に挿入している。この無名で見えないクラスがモジュールにリンクされ、両者はインスタンスメソッドと定数を共有する
  • Rubyは、メソッドを探すときに、最後にインクルードされたモジュールから順にたどっていく。最後の階層まで探しているメソッドが見つからなかったときには、method_missingを探してもう一周サーチを行う
  • 継承階層の上位にあるメソッドをオーバーライドするときは、メソッド内でsuperを使ってオーバーライドされるメソッドを呼び出すことができる。引数もかっこも付けずにsuperを呼び出すと、呼び出し元のメソッドに渡されたすべての引数を渡してオーバーライドされるメソッドを呼び出すという意味になる。オーバーライドされるメソッドに引数を渡さずにsuperを使いたい場合は、super()のように空のかっこを使う必要がある
  • Rubyは、サブクラスのオブジェクトを作るときに、スーパークラスのinitializeメソッドは自動的に呼び出さない。initializeにも通常のメソッドルックアップの規則が適用され、最初に見つかったバージョンが実行される。スーパークラスのinitializeメソッドを使いたいときはsuperを用いる
  • セッターメソッドは、明示的にレシーバを指定しなければ呼び出せない。レシーバがなければ、変数への代入と解釈されてしまう。インスタンスメソッドからセッターメソッドを呼び出すときには、レシーバとしてselfを使う
  • 新しいクラスを作るほどでもない構造化データを扱うときには、HashではなくStructを使うようにすべき。Struct::newの戻り値を定数に代入し、その定数をクラスのように扱う
  • トップレベル定数を修飾なしで使うと曖昧になるときには、”::”を使ってフルに修飾する(例 ::Array)
  • equal?メソッドは、厳格にオブジェクトを比較し、両方が同じobject_idを持たない限りtrueを返さない
  • 2つのオブジェクトが同じ値を表すかどうかをテストするときには”==“演算子を使う
  • case式は、個々のwhen節をテストするために”===“演算子を使っている。左被演算子はwhenに与えられる引数、右被演算子はcaseに与えられる引数である
  • オブジェクトの順序は、”<=>”演算子を定義し、Comparableモジュールをインクルードすれば実装できる。”<=>”演算子は、左被演算子が右被演算子と比較できないものはnilを返す。左被演算子の方が小さいときは-1、大きいときは1、等しいときは0を返す
  • Rubyがprivateメソッドに加えている制限は1つだけで、privateメソッドは明示的なレシーバを指定して呼び出すことができないことである
  • protectedメソッドは、関連するクラスの間でプライベートな情報を共有するために作られる。レシーバを明示してprotectedメソッドを呼び出せるのは、同じクラスのオブジェクトか共通のスーパークラスからprotectedメソッドを継承しているオブジェクトだけである
 

第3章 コレクション

  • Rubyのメソッド引数は値渡しではなく参照渡しである。ただし、この規則には、Fixnumオブジェクトという例外がある
  • 引数として渡されたコレクション(配列やハッシュ)は、書き換える前にdup、cloneメソッドでコピーをつくるべきである(ほとんどの場合dupの方が良い)。メソッドに引数として渡されたコレクションを書き換えてしまう誤りはよくある
  • reduce(inject)は、関数型プログラミングの世界で畳み込みと呼ばれる関数で、あるデータを別のデータ構造に変換する、非常に強力な関数である
  • 以下例の動作は、イテレーションのたびに、ブロックは現在のアキュムレータと現在の要素を受け取り、それらを加える。この和はブロックの戻り値になり、次のイテレーションのアキュムレータになる。このプロセスは、ブロックにすべての要素が渡されるまで繰り返され、reduceはアキュムレータの最終的な値を返す
    enum.reduce(0) do |accumulator, element|
      accumurlator + element
    end
  • reduceに与えられる引数は、アキュムレータの初期値である。引数(初期値)を省略するとレシーバの先頭の要素をアキュムレータとして扱い、第2要素からイテレーションをスタートさせるが、レシーバが空の時nilを返す挙動となってしまうので、常に初期値は設定すべきである(初期値が設定されておりレシーバが空の時は初期値を返す挙動となる)
  • reduceを使えば、よく使われるmap・selectなどを使うよりも効率の良いコードにできることがある。reduceのブロックは、新しいアキュムレータさえ返していれば、与えられたアキュムレータと要素に何でも自由に操作を加えられる
 

第4章 例外

  • raiseの第1引数としてクラス名を指定できる。その場合、指定されたクラスの例外オブジェクトを作り、それを使って例外を生成する。クラス名を指定しない場合、RuntimeErrorクラスとなる。第2引数(オプション)はエラーメッセージとして使う文字列を渡すことができ、指定しない場合はクラス名となる
  • 修復方法がわかっている特定の例外だけをrescueで捕まえるようにする。例外を捕まえるときは、もっとも限定されたタイプのものを最初に書く
  • StandardErrorのような汎用例外クラスをrescue節で捕まえるのは避ける。操作を加えたいときは、ensure節で代用できないかを考える
  • rescue節の中で例外を生成するときは、raise(e) のようにして元の例外をraiseする
  • 例外が発生するかもしれないときは、確保したリソースを解放するためにensure節を使うとよい。ensure節は正常な条件でも例外条件でも実行される
 

第5章 メタプログラミング

  • クラス、モジュール、個々のオブジェクトのふるまいなどをプログラムの実行中に変更できるメタプログラミングは、Rubyのもっとも強力な機能の1つであり、もっとも危険な機能の1つでもある
 

第6章 テスティング

  • テストを書くときは、失敗するようなテストを書く。コードの重要な部分をコメントアウトし、その部分のテストが失敗するようにする
  • バグの根本原因を探し始める前にそのバグのために失敗するテストを書くバグフィックスの最初のステップはバグの再現であり、そのバグの専用のテストを用意すれば、フィックス後に再度バグが発生することを避けられる
 

第7章 ツールとライブラリ

  • Bundlerは、gemの依存を自動的に管理し、開発中に使っているgemセットとまったく同じものを他のデベロッパーや本番サーバも使うようにしてくれる。必要なgemは、Gemfileで指定する。Bundlerは、指示を受けると必要なすべてのgemとそれらの依存関係をインストールする。また、依存全体を格納するGemfile.lockを作成、更新する
 

第8章 メモリ管理とパフォーマンス

  • 実行中のRubyプログラムはオブジェクトから構成される。オブジェクトは無数にあり、たとえば、irbを新しく起動すると、10万個くらいのオブジェクトが作られ、ガベージコレクタが作動すると、アクティブオブジェクトの数は1万2千個くらいに削減される。Rubyにはガベージコレクタがあるので、マニュアルでメモリを管理する必要は無いが、ガベージコレクタが正しい処理をするためには実行中のプログラムを一時停止させなければならないので、パフォーマンスが少し下がってしまう
  • パフォーマンスの低いコードを書き換えるときは、まずプロファイリングツールを使って状況を確認するべき
  • ループ(eachブロックなど)内で使うオブジェクトが書き換えられないのであれば、オブジェクトリテラル定数とすることで、メモリ確保の回数が減り、ガベージコレクタが起動するリスクを下げることができる

 

おわりに

ここまで読んでいただきありがとうございます。 

本書にはコードを用いた具体例が多くてとても分かりやすかったので、気になる方はぜひ本書をご覧ください。 

Effective Ruby

Effective Ruby

 

次は、リーダブルコード を読む予定です。

来週も頑張ります! 

【技術書まとめ21】達人に学ぶ SQL徹底指南書

毎週1冊技術書を読んでブログでアウトプットすることが目標で今回が第21弾です。

今回は、達人に学ぶ SQL徹底指南書 を読みました。

SQL正しい書き方・考え方について丁寧に解説している本です。

特にSQLのパフォーマンスチューニングのところは、すぐに仕事で実践できる具体的な内容で、それ以外のところも知らなかったことが多くとても勉強になったので、SQLに自信がない方は是非ご覧ください。

このまとめには概要だけを書くことでポイントを覚え、実際に使う際に本書の該当箇所にすぐたどり着けるようにしています。

f:id:ysk_pro:20190302170027p:plain

第1部 魔法のSQL

CASE式のススメ

  • CASE式を活用するとSQLでできることの幅がぐっと広がり、書き方もスマートになる
  • CASE式には、単純CASE式と検索CASE式がある。検索CASE式の方ができることが多いので、検索CASE式を用いることが多い
  • CASE式を使い、SELECT句で条件分岐させるとスッキリかけることがある
  • CASE式は、明示的なELSE句がない場合、デフォルトでELSE NULLと見なすという仕様があるので注意が必要
  • DECODE関数などと比べた時にCASE文の大きな利点は、式を評価できる点。つまり、CASE文の中でBETWEEN、LIKE、<、IN、EXISTSなどの便利な述語群を使用できる
  • CASE式は実行時に評価されて1つの値に定まるので、列名や定数をかける場所には常に書くことができる
  • CASE式を駆使することで複数のSQL文を1つにまとめられ、可読性もパフォーマンスも向上する

 

必ずわかるウィンドウ関数

  • ウィンドウ関数のウィンドウとは、範囲という意味である
  • ウィンドウ関数は移動平均を求める場合などによく利用される
  • ウィンドウ関数は以下の操作を1つの関数に詰め込んでいる
    • PARTITION BY句によるレコード集合のカット
    • ORDER BY句によるレコードの順位付け
    • フレーム句によるカレントレコードを中心としたサブセットの定義
  • SQLの内部動作を知るには、「実行計画(execution plan)」を調べればよい。実行計画とは、DBMSSQL文を実行する際に、どのようなアクセス経路でデータを取得し、どのような計算を行うことが最も効率的かを判断するために作るものである

 

自己結合の使い方

  • 同一のテーブルを対象に行う結合を自己結合(self join)と呼ぶ
  • 自己結合は基本的に非等値結合と組み合わせて使われる
  • 自己結合は異なるテーブルを結合していると考えると理解しやすい

 

3値論理とNULL

  • 普通のプログラミング言語の真理値型(BOOLEAN型)とSQLの真理値型の違いは、普通の言語はtrue、falseという2つの値を持つのに対し、SQLはそれに加えてunknownという第三の値を持つことである。2つの真理値だけを持つ通常の論理体系が2値論理と呼ばれるのに対し、SQLの論理体系は3値論理と呼ばれて区別される
  • NULLに比較述語(=や > など)を適用した結果は常にunknownになってしまうのは、NULLが値でも変数でもないためである。NULLは、そこに値がないことを示すただの視覚的マーク、目印に過ぎないのに対し、比較述語を適用できるのは値だけなので、NULLに比較述語を適用してもunknownとなってしまう
  • 3つの真理値の間には次のような優先順位があり、強い方が弱い方をのみ込む
    • ANDの場合:false > unknown > true(例:false AND unknown -> false)
    • ORの場合:true > unknown > false
  • unknownが論理演算に紛れ込むと、SQLが直感に反する動作をしてしまう。これに対処するには、段階的なステップに分けてSQLの動作を追うことが有効

 

EXISTS述語の使い方

  • EXISTSは、SQLにおいて量化を表現する重要な述語である。述語とは、戻り値が真理値(true、false、unknown)となる関数のこと
  • EXISTS以外の述語(=や>など)は1行を入力とするのに対し、EXISTSは行の集合を入力とする
  • 「全ての行について〜」という全称量化の表現を、「〜でない行が1つも存在しない」という二重否定分に変換し、NOT EXISTSを使う方法がよく使われる

 

HAVING句の力

  • 現在の標準SQLでは、HAVING句を単独で使うことができる
  • WHERE句が集合の要素の性質を調べる道具であるのに対し、HAVING句は集合自身の性質を調べる道具である
  • SQLで検索条件を設定するときは、検索対象となる実体が集合なのか集合の要素なのかを見極めることが基本である
    • 実体1つにつき1行が対応している → 要素なのでWHERE句を使う
    • 実体1つにつき複数行が対応している → 集合なのでHAVING句を使う

 

ウィンドウ関数で行間比較を行う

  • ウィンドウ関数を用いれば行間比較(異なる行の間で列同士を比較)することが簡単にできる。相関サブクエリでも同じことはできるが、パフォーマンス面、可読性の面でウィンドウ関数の方が優れている
  • ウィンドウ関数は、サブクエリを使っているが、相関サブクエリではない。そのため、サブクエリ単体でも実行できるので、可読性が高く動作を理解しやすい。サブクエリ内部だけで実行することで、デバッグも容易に行うことができる

 

SQLで集合演算

  • 集合演算子は重複排除のために暗黙のソートが発生するので、ALLオプションをつけるとソートが行われなくなりパフォーマンスが向上する。よって、重複を気にしなくていい場合、または重複が発生しないことが確実な場合はにはALLオプションをつけるとよい
  • UNIONとINTERSECTは冪等性を持つ

 

SQLを速くするぞ

  • SQLパフォーマンスチューニング
    • 効率の良い検索を利用する
      • サブクエリを引数に取る場合、INよりもEXISTSや結合を使う
    • ソートを回避する
      • ソートが発生する代表的な演算は次の通り
        • GROUP BY句
        • ORDER BY句
        • 集約関数(SUM、COUNT、AVG、MAX、MIN)
        • DISTINCT
        • 集合演算子(UNION、INTERSECT、EXCEPT)
        • ウィンドウ関数(RANK、ROW_NUMBER等)
      • ソートがメモリ上で行われてる間はまだいいが、それでは足りずにストレージを使ったソートが行われるとパフォーマンスが大きく低下する
      • 集合演算子のALLオプションをうまく使う:重複を気にしなくてよい場合、重複が発生しないことが明らかな場合は、ソートが発生しないALLオプションをつけて使う
      • DISTINCTをEXISTSで代用する:2つのテーブルを結合した結果を一意にするためにDISTINCTを使っているケースでは、EXISTSで代用することでソートを回避することができる
    • 極値関数(MAX/MIN)でインデックスを使う
    • WHERE句でかける条件はHAVING句には書かない:GROUP BY句による集約はソートなどを行うので事前に行数を絞り込んだ方がよく、うまくいけばWHERE句でインデックスが利用できるため
    • GROUP BY句とORDER BY句でインデックスを使う
    • インデックスが使われない書き方
      • 索引列に加工を行なっている
      • インデックス列にNULLが存在する
      • 否定形を使っている
      • ORを使っている
      • 後方一致、または中間一致のLIKE述語を用いている
      • 暗黙の型変換を行なっている
    • 中間テーブルを減らす:中間テーブルの問題点は、データを展開するためにメモリを消費することや、元テーブルに存在したインデックスを使うのが難しくなることである
      • 中間テーブルを使うのではなく、HAVING句を活用する
      • IN述語で複数のキーを利用する場合は、一箇所にまとめる
      • 集約よりも結合を先に行う
    • レコード数を絞れる条件は早い段階で記述する
  • SQLにおいて、最大のボトルネックになるのはストレージへのアクセスである。ソートを減らすのも、インデックスを利用するのも、中間テーブルを省略するのも、すべてストレージへのアクセスを減らすことを目的にしている
  • SQLの実行順序は、FROM → WHERE → GROUP BY → HAVING → SELECT (→ ORDER BY)である(ORDER BYは正確にはSQLの一部ではないのでカッコとしている)。複雑なSQLを書くときは、いきなりSELECT句から書くより、実行順序に沿ってFROM句から書いた方が自然にロジックを追える
 

第2部 リレーショナルデータベースの世界

  • 2000年代に、RDBの欠点であるパフォーマンスのスケーラビリティや非構造化データの扱いといった問題がクローズアップされるようになり、それに対する解決策としてNoSQLが登場してきた
  • NoSQLには明確な定義はなく、RDBとは異なるアーキテクチャやデータモデルに基づくデータベースという程度のゆるい定義である
  • NoSQLの一つに、KVS(Key-Value Store)がある。KVSは、キーとそれによって一意に決まる値という非常にシンプルな構造しか持たない。Redisやmemcachedなどの製品がKVSの機能を備えている
  • NoSQLには、ドキュメント指向型DBと呼ばれるタイプもある。JSONXMLのような自由度の高いドキュメントを、RDBのテーブルに変換することなくネイティブに扱う機能を持つ。製品としては、MongoDB、CouchDBなどが該当する
  • NULLについては、まず以下のようにデフォルト値を入れられないか検討し、どうしようもない場合のみNULLを許可するのがよい
    • フラグなどのコードの場合、未コード化用のコードを割り振る
    • 名前の場合、名前が不明用の値を決めて用いる
    • 数値の場合、0で代替する
    • 日付の場合、0000-01-01や9999-12-31のように最大値・最小値で代替する
 

おわりに

ここまで読んでいただきありがとうございます。 

具体例が多くとても分かりやすかったので、気になる方は是非本書をご覧ください。

次は Effective Ruby を読む予定です。

来週も頑張ります!

【技術書まとめ20】達人に学ぶDB設計 徹底指南書

毎週1冊技術書を読んでブログでアウトプットすることが目標で今回が第20弾です。

 

今回は、達人に学ぶDB設計 徹底指南書 を読みました。

DB設計の基礎知識やポイントを丁寧に解説している本です。

 

中でも、インデックスを作成するかどうかの指針が書かれているところは、実務で悩んだことがあったのでとても参考になりました。

一からアプリケーションを作る時以外でも、テーブルやカラム追加の際に為になる知識も多かったので、DB設計に自信がない方は是非読んでみて欲しいです。 

達人に学ぶDB設計 徹底指南書

達人に学ぶDB設計 徹底指南書

 

f:id:ysk_pro:20190209145325p:plain

第1章 データベースを制する者はシステムを制す

  • データとは、ある形式(フォーマット)に揃えられた事実のこと。情報とは、データをある文脈・観点に従って集約・加工されたものである
  • データベース設計が重要な理由
    • システムの大半のデータはデータベース内に保持されるため
    • データ設計がシステムの品質を最も大きく左右するため。どのようなプログラムが必要になるかは、どのようなデータをどういうフォーマットで保持するかに左右される
  • データベースの設計は、3層スキーマモデルという3つのレベルに分けて行う
    • 外部スキーマ:ユーザーから見たデータベースで、テーブルやビューのこと(画面やデータ)
    • 概念スキーマ:開発者から見たデータベースで、テーブル定義のこと(データの要素やデータ同士の関係)
    • 内部スキーマDBMSから見たデータベースで、データの物理的配置のこと(テーブルやインデックスの物理的定義)
 

第2章 論理設計と物理設計

  • 概念スキーマを定義する設計を論理設計と呼び、論理というのは物理層の制約にとらわれないという意味である
  • 論理設計は次の4つのステップからなる
    • エンティティ(現実世界に存在するデータの集合体)の抽出:エンティティをテーブルとする
    • エンティティの定義:テーブルにどのようなカラムを持つか定義する
    • 正規化
    • ER図の作成
  • 論理設計の結果を受けて、データを格納するための物理的な領域や格納方法を決める工程が物理設計である
  • 物理設計には、大きく分類して次の5つのタスクが含まれる
    • テーブル定義
    • インデックス定義
    • ハードウェアのサイジング
    • ストレージの冗長構成決定
    • ファイルの物理配置決定
 

第3章 論理設計と正規化 〜なぜテーブルは分割する必要があるのか?

  • テーブル名は必ず複数形で書ける。そうでなければそのテーブルにはどこかに間違いがある
  • 主キーは、テーブルに必ず一つだけ存在する。主キーとは、その値を指定すれば必ず1行のレコードを特定できる列の組み合わせ。主キーがテーブルに存在しなければならないので、重複行は存在し得ない
  • 外部キーは、2つのテーブル間の列同士で設定するもので、参照整合性制約を課すことが役割である
  • NULLはSQL上で扱う際にいろいろな問題を引き起こすので、可能な限りデータはNULLにしないというのがデータベース設計における大方針。可能な限りNOT NULL制約を付加する
  • 正規形とは、データベースで保持するデータの冗長性を排除し、一貫性と効率性を保持するためのデータ形式。正規形のレベルは第5まであるが、通常は第3正規形までで十分である
    • 第1正規形は、一つのセルの中には一つの値しか含まないというもの
    • 第2正規形は、テーブル内で部分関数従属(主キーの一部の列に対して従属する列の関係)を解消し、完全関数従属のみのテーブルを作ることである。第2正規化は、異なるレベルのエンティティをテーブルとして分離する作業と言い換えることもできる
    • 第3正規化は、テーブル内での推移的関数従属(段階的な従属関係)を解消すること
  • 正規形はいつでも非正規形に戻すことができる。つまり、高次の正規形は低次の正規形を含んでいる
  • 正規化の欠点は、テーブルの数が増えるためにSQLで結合を多用することになり、パフォーマンスが悪化すること
 

第4章 ER図 〜複数のテーブルの関係を表現する

  • 多数のテーブルを管理するために、それぞれのテーブルがどういう意味を持っていて、テーブル同士が互いにどういう関係にあるのかを明示するために作る図をER図(Entity-Relationship Diagram)と呼ぶ
  • ER図を描くときに最初に着目するポイントは、あるテーブルの主キーが、他のテーブルに列として含まれているかどうかである
 

第5章 論理設計とパフォーマンス 〜正規化の欠点と非正規化

  • 正規化がパフォーマンス問題を引き起こす原因は、正規化するとSQL文の中で結合(join)が必要になることである。結合はSQLの処理の中でもコストが高く、多用するとSQLの速度が低下する
  • 正規化と検索SQLのパフォーマンスは強いトレードオフの関係にあるが、パフォーマンスを重視して非正規化することは最後の手段として考えるべきである
 

第6章 データベースとパフォーマンス

  • データベースのパフォーマンスを決める主な要因は、ディスクI/Oの分散(RAID)、SQLにおける結合(正規化)、そしてインデックスと統計情報である
  • インデックスを使うかどうかは、DBMSが自動的に判断する。したがって、インデックスを使う場合は単純にデータベース側にインデックスを作成すればよく、アプリケーションプログラムの変更の必要はない
  • 最もよく使われるB-treeインデックスは、木構造でデータを保持する。最下層のリーフと呼ばれるノードだけが、実データに対するポインタを保持しており、データベースは最上位のノードから順にノードをたどって、リーフから実データを見つける
  • B-treeは、等号による検索のみならず、不等号やBETWEENといった範囲検索の条件に対しても高速化を可能とする。反対に、否定条件はB-treeが効果を持たない
  • ソートはかなりコストの高い演算であり、極力大きなソートを避けることがパフォーマンス上望ましい。COUNT、SUM、MAX、UNIONなどの処理でも暗黙にDBMS内部でソートが行われている。B-treeインデックスは、構築時にキー値をソートして保持するため、B-treeインデックスが存在する列をソートのキーとして指定した場合は、ソート処理をスキップすることが可能でパフォーマンスが向上する
  • B-treeインデックスを作る指針
    • 大規模なテーブル:レコード数が1万件以下の場合はほぼ効果はない
    • カーディナリティの高い列:カーディナリティとは、特定の列の値がどのくらいの種類の多さを持つかという概念。例えば性別で、男性・女性・不詳が入る場合、カーディナリティは3となる。特定のキー値を指定した時に、全体のレコード数の5%程度に絞り込めるだけのカーディナリティがあることが目安となる
    • SQL文でWHERE句の選択条件、または結合条件に使用されている列に作成する
  • インデックスが利用できていないパターン
    • インデックス列に演算を行なっている:インデックスを作成した列はSQLでそのまま用いるのが原則
    • 索引列に対してSUBSTRなどのSQL関数を適用している
    • IS NULL述語を使っている:B-treeインデックスは一般的にNULLについてはデータの値と見なさず、保持していない
    • 否定形を用いている
    • ORを用いている:INで書き換えることでインデックスを用いることは可能
    • 後方一致、または中間一致のLIKE述語を用いている:LIKE述語を使うときは、前方一致検索の場合のみインデックスが使用される
    • 暗黙の型変換を行なっている:列とデータ型の異なる値を条件に指定した場合、DBMSは内部的に暗黙の型変換を行うが、その場合はインデックスは使用されなくなる
  • DBMSの主キー制約や一意制約を作成する際には、内部的にはB-treeインデックスを作成しているので、インデックスの作成は不要である
  • インデックスは一般的にテーブルとは独立のオブジェクトとしてDBMS内部に保持される。そのため、インデックスが作成されている対象の列の値が変更されると、インデックス内に保持している値も変更しなければならず、インデックスは更新性能を劣化させてしまう
  • インデックスは、テーブルのデータが更新されていくと、長期的には構造が崩れて性能が劣化してしまう。そのため、運用において定期的なメンテナンスを行うべきである。具体的には、インデックスの再構築を行うことが性能を維持するためには望ましい
  • 統計情報とは、テーブルやインデックスなどのデータについてのデータ、すなわちメタデータである。DBMSはこのメタデータを頼りにSQLのアクセスパスを決定している
  • DBMSSQLを受け取ると、まずパーサに渡される。パーサはSQL文が適法な構文であるかをチェックする役割を持つ。パーサによるチェックが済むと、SQLオプティマイザに送られる。オプティマイザはSQLの実行計画を決めるDBMSの頭脳である。オプティマイザが実行計画を立てる際に必要なのが統計情報で、統計情報はカタログマネージャから受け取る。統計情報を受け取ると、オプティマイザは最短の経路を選択し、SQLを手続きに変換する。このとき得られた手続きの手順が実行計画で、これにしたがって実データであるテーブルにアクセスを行う
  • 統計情報はデータが大きく更新された後は、なるべく早く収集すべきである。統計情報を収集するのは、それなりにリソースを消費する処理であるので、基本的にはシステムの使用者が少ない夜間帯に実施する。また、統計情報の収集はDBMSによっては、デフォルトの設定で定期的に実施されていることもある
 

第7章 論理設計のバッドノウハウ

  • データベースには、意味的に分割できる限りなるべく分割して保持するのが基本方針。分割したものを後で結合するのは簡単にできるのに対し、結合された状態のものを後から分割するのは比較的難しいためである
  • バッドノウハウがよくないのは、システムの品質を左右する上、後から変更するのが容易ではないためである
 

第8章 論理設計のグレーノウハウ

  • 子1、子2、子3のようなカラムを持つ列持ちテーブルは、NULLを使わざるを得なくなるので、極力使うべきではない。基本的には行持ちテーブルを使うべきである
 

第9章 一歩進んだ論理設計 〜SQL木構造を扱う

  • リレーショナルデータベースでは、木(tree)構造を表現するのが苦手である
  • 木構造を表現する方法には、伝統的な隣接リストモデルや、近年できた入れ子集合モデル、入れ子区間モデル、経路列挙モデルがあり、それぞれにメリットデメリットがある

 

おわりに

ここまで読んでいただきありがとうございます。 

具体例も多くとても分かりやすかったので気になる方は是非本書をご覧ください。

達人に学ぶDB設計 徹底指南書

達人に学ぶDB設計 徹底指南書

 

次は同じシリーズのSQLの本を読むつもりです。

来週も頑張ります!

 

 

【技術書まとめ19】アジャイルな見積もりと計画づくり

毎週1冊技術書を読んでブログでアウトプットすることが目標で今回が第19弾です。

 

今回は アジャイルな見積もりと計画づくり を読みました。

アジャイル開発について詳しく解説をしている名著です。

 

アジャイルについて全く知識・経験がなかったですが考え方がとても合理的で面白かったです。

この記事を読めばアジャイルについての概要がつかめると思うので、興味ある方は是非読んでみてください。

今回は学ぶことが多かったので少し長めです。

f:id:ysk_pro:20190126103827p:plain

まえがき

  • アジャイル開発者の主張は次の通り。「私たちは今ここで分かっていることを元に計画を立てる。顧客にとって一番大切な目標を達成するために私たちは計画を変更する。プロジェクトが進んで新たな知識を得たら、それにプロジェクトと計画を適応させる。私たちから顧客への願いは、ビジネスの変化へ柔軟に適応することと当初の計画を死守するとことは矛盾した要求だと、きちんと理解してほしいということである」
  • 多くのプロジェクトマネジメント手法は「計画ー計画ー計画ー実行」であるのに対し、アジャイル手法は「計画ー実行ー適応」の繰り返しである。プロジェクトの不確実性が多ければ多いほど、成功するためにはアジャイル手法が必要となる
  • プロダクトマネージャやプロジェクトマネージャに、専門的スキルを持つ人の仕事の進め方と仕事内容を決定する権限を与えてしまうのは、ビジネス的自殺といってもよい
  • アジャイルな見積もりと計画づくりの手法が従来型の手法よりも効果的な理由は、価値を提供することとビジネスとプロジェクトチームの間に信頼関係を築くことに注力しているためである。どんなことにも透明性を保ち、いかなる変更でもビジネス側に伝えることで、ビジネス側も素早く適応し、最善の判断を下すことができる
 

第1部 問題とゴール

1章 計画の目的

  • プロジェクトが進むにつれて見積もりは正確になる。「不確実性コーン」によれば、初期のプロジェクト定義の段階では見積もりには60%から160%に及ぶ誤差が生じる
  • よい計画とは、ステークホルダーが信頼できる計画である。信頼できるとは、その計画を基にして意思決定できるということである
  • アジャイルな計画づくりを定義すると以下のようになる
    • 計画よりも計画づくりを重視する
    • 変化を促進する
    • 計画そのものは容易に変更できる
    • プロジェクト全体にわたって繰り返される
 

2章 なぜ計画づくりに失敗するのか

  • 仕事の量は、完成のために与えられている時間をすべて満たすまで膨張する。これはパーキンソンの法則と呼ばれており、私たちは作業完了までの期間が決まっていると、許される限りの時間をすべて使ってしまう
  • マルチタスク化は生産性に甚大な悪影響を与え、遅れを助長する。個人が3つ以上の作業を並行して進めると、価値を生み出す作業に使える時間が大幅に減少することが分かっている
  • 不確実性に対処する最善の方法は、繰り返すことである。プロダクトがどうあるべきかという不確実性を低減させるには、短いイテレーションで作業するとよい
 

3章 アジャイル手法

  • アジャイルチームの基本的な仕事の進め方
    • 1つのチームとして働く:すべてのプロジェクト参加者が、共通のゴールを持った1つのチームに参加している意識を持つ
    • ビジネス上の優先度を重視する
    • 検査と適応
  • プロジェクトというものは新たな機能と知識を生み出し続ける活動であり、単に決められた手順を実行するだけではない
  • アジャイルチームは3つのレベルで計画づくりをする
    • リリースプランニング:リリース全体についての計画であり、3ヶ月から6ヶ月という期間がよく使われる
    • 今日のプランニング:日々のスタンドアップミーティングでメンバーがその日に何をするか決めた1日単位の計画
  • プロダクトオーナーの満足条件を理解せずに、リリースプランニングとイテレーションプランニングはできない
 

第2部 規模を見積もる

4章 ストーリーポイントによる規模の見積もり

  • ストーリーポイントとは、ユーザーストーリーやフィーチャ、その他の作業の大きさを表す単位である。ストーリーポイントを使った見積もりでは、ひとまとまりの仕事に対してポイントをつける。ポイントの数値そのものは重要ではなく、他の作業との相対値が重要である
  • ストーリーポイントによる見積もりの始め方には2種類ある。これから取り組むストーリーの中で最も小さいと思えるものを基準としてそれを1ポイントとする方法と、中くらいと思えるストーリーを決めて、それに見積もりで使う数値範囲の中央に近い値をつける方法である
  • ベロシティとは、チームの進む速度を表す単位である。ベロシティの値は、チームが1回のイテレーションで完了させたユーザーストーリーのストーリーポイントの合計値である。チームが前回のイテレーションで10ストーリーポイント分の作業を完了させたのであれば、次のイテレーションでも10ストーリーポイント分の作業をこなせると予測できる
  • 必要なすべてのフィーチャのストーリーポイントの見積もりを合計すれば、プロジェクト全体の規模を見積もれる。また、チームのベロシティがわかれば、規模をベロシティで割ると必要なイテレーションの回数が見積もることができる。イテレーション数とは期間なので、カレンダーに当てはめればそれがスケジュールとなる
  • アジャイルな見積もりでは「規模を見積もり、期間は導出する」
  • プロジェクトが進捗するということはユーザーストーリーをこなしていくことなので、数イテレーションも実施すればチームのベロシティがわかってくる。ポイントによる見積もりの素晴らしい点は、ベロシティを適用することで計画時の見積もりミスが自動的に補正されることである
 

5章 理想日による見積もり

  • ユーザーストーリーの開発にかかる時間は、現実日で見積もるよりも理想日で見積もる方が簡単である。現実日による見積もりでは、ストーリーの完了までに起こりうる、あらゆる割り込みを考慮しなくてはならない。理想日による見積もりなら、ストーリーに必要な時間だけを検討すればよい
 

6章 見積もりの技法

  • わずかな時間で考えた見積もりと、長時間悩んだ末に出した見積もりがほとんど同じになるのはよくあることである。ある程度以上の労力を費やしても、見積もりの正確さには寄与しない
  • 見積もりはチーム全体で出した方がよいアジャイルプロジェクトでは誰がどの作業をするのか事前に分からないことが多く、作業を担当するメンバー以外の意見も参考にした方が良いため
  • 人は10倍以内のものならうまく見積もれるという研究結果がある。見積もりのスケールには「1, 2, 3, 5, 8」というフィボナッチ数列をよく用いる
  • プランニングポーカーは、専門家の意見、対比、分割の全てを組み合わせ、楽しみながら迅速かつ信頼できる見積もりを出すことができる。プランニングポーカーの参加者はチームの開発者全員である
    • まず最初に、全員に一組のカードを配り、そこにはチームで使用できる見積もりポイントが1枚につき1つずつ書かれている
    • 進行役となる人が、見積もり対象のユーザーストーリーやテーマを1つずつ読み上げ、見積もり担当者からの質問にはプロダクトオーナーが回答する
    • 見積もり担当者は、自分がこうだと思う見積もりポイントのカードを選ぶ。選んだカードは全員が選択し終えるまで人には見せないようにし、全員の見積もりが決定したら一斉にカードをオープンする
    • 人によって見積もりが大きく異なることは、見識の相違から学ぶチャンスである。高い見積もりを出した参加者と低い見積もりを出した参加者に、見積もりの根拠を説明してもらう。この時、見積もった人を非難しているように見えないよう留意する
    • 議論を終えたら、見積もり担当者はそれぞれ再び見積もりポイントカードを選んで、一斉にオープンする
    • 多くの場合、見積もりは第2ラウンドで収束するが、収束しなければここまでの手順を繰り返す。ゴールは、全員が合意することにある
  • プランニングポーカーがうまくいく理由
    • 複数の専門家の見解をまとめた見積もりを実現するため
    • 活発な対話を引き出すため。見積もりについて説明を求めると、情報の不足を補ったよりよい見積もりとなる
    • 個人の見積もりを平均した方がよりよい結果を残す傾向があるという研究結果があるため
    • 楽しいため
 

7章 再見積もり

  • 再見積もりが必要となるのは、ストーリーの相対的な規模に変化があったとチームが判断した時(例えば、あるシナリオだけがより時間を要すことがわかった場合など)である。あるストーリーが想定よりも長く時間を要したというだけでは再見積もりはしない
 

8章 ストーリーポイントと理想日

  • ストーリーポイントは純粋な大きさのみを測定する値だが、理想日はそうではない。開発者のスキルが変化すれば理想日の見積もりも変化してしまうが、ストーリーポイントではこうしたことは起きない
  • 理想日は人によって異なってしまうが、ストーリーポイントは人によって異なることはない
 

第3部 価値のための計画づくり

9章 テーマの優先順位づけ

  • 新しいフィーチャの優先順位づけに必要な4つの要素
    • フィーチャの金銭価値
    • フィーチャの開発(サポートも含む)にかかるコスト
    • フィーチャの開発を通じて学べる知識の量とその意義
    • フィーチャの開発によって低減できるリスク
  • 4つの要素を総合して優先順位をつけるとき、第一に考えるのはフィーチャの価値とそのフィーチャを開発するのにかかるコストである。コストに対して最も高い価値を持つテーマが、最初に着手すべきテーマとなる。さらに、他の優先順位づけの要素を検討してテーマの優先順位を上下する
 

10章 金銭価値による優先順位づけ

  • 財務的に分析することは優先順位づけに役立つ。利益と業務改善の効果を予想するのは2年先までが一般的である
  • キャッシュフローの評価には、正味現在価値、内部収益率、回収期間、割引回収期間の4つの指標を利用する
 

11章 「望ましさ」による優先順位づけ

  • 顧客満足度の狩野モデル
    • 当たり前、または必須のフィーチャ:フィーチャをどれだけ幅広く用意して、品質に磨きをかけても、当たり前のフィーチャであれば顧客満足度にほとんど影響を与えない
    • 線形、一元的なフィーチャ:あればあるほどよいもの。線形、一元的というのは、フィーチャの量に比例して顧客満足度が線形に高まることに由来する
    • 魅力的な、わくわくするフィーチャ:大きな満足をもたらしたり、わくわくする気持ちになったりするもの。このフィーチャは無いからといって顧客満足度が悪くなることはない。ユーザーは体験してみるまで、そうしたフィーチャが必要だということに気づかない
  • 当たり前のフィーチャを備えたら、線形のフィーチャをできるだけ多く完成させることを重視する。魅力的なフィーチャはこれらの機能を実装した後に、時間の許す範囲で対応する
  • ユーザーからアンケートを取ることで、フィーチャを簡単にカテゴリに分類することができる
 

12章 ユーザーストーリーの分割

  • 1つの大きなストーリーを見積もるよりも、分割して見積もった方が正確な見積もりになる
  • ユーザーストーリーを分割するタイミング
  • 大きなストーリーは、ストーリーで行う操作に沿って分割する。よくあるのは、CRUD操作を境界として分割することである
  • チームのイテレーション期間が2週間であれば、2日から5日で完了できる大きさにストーリーを分割するのが適切な大きさである
 

第4部 スケジュールを立てる

13章 リリース計画づくりの基本

  • 一般的には、3ヶ月から6ヶ月の周期でリリースを繰り返すことが多い
  • リリース計画は定期的な見直しと更新が必須である。多くのプロジェクトがイテレーション終了時点でリリース計画を見直すようにルールを定めている
 

14章 イテレーション計画づくり

  • イテレーションプランニングではタスクの担当者は決めない。タスクの担当者を決めるのは、イテレーションが始まってからである。また、一度に担当するタスクは1つであり、新しいタスクに着手するのは、前に担当したタスクを完了させてからである。イテレーションが始まる前に、全てのタスクの担当者を決めてしまうと、イテレーションのゴールに向かってチーム全員が一丸となって取り組むという参加意欲に水を差してしまう
  • アジャイルな計画づくりは二段階に分かれている。第一段階はリリース計画であり、この段階の計画は荒削りで全体的に不確定な部分が残っている。第二段階がイテレーション計画である。イテレーション計画は新しいイテレーションを始めるタイミングで実施するので、プロジェクトの中でチームが得た新しい知識を使ってリリース計画よりも詳細な計画を立てられる
  • リリース計画が3ヶ月から6ヶ月の期間を対象とするのに対し、イテレーション計画は1回のイテレーションだけを対象とする。リリース計画で扱う比較的大きなユーザーストーリーを、イテレーション計画ではタスクに分解する。ストーリーを分解したタスクは完了までの理想時間を単位として見積もる
  • イテレーション計画には、ユーザーストーリーをプロダクトに統合して動作させるために必要な全てのタスクを含めるべきである
  • タスクのサイズは、開発者が平均して1営業日に1つ完了できるくらいの大きさが適切である
 

15章 イテレーションの長さを決める

  • ほとんどのアジャイルチームは2週間から4週間のイテレーションを採用しているイテレーションの長さは、以下の要素を考慮して決めるのが良い
    • リリースまでの期間
    • 不確定要素の高さ
    • フィードバックの得やすさ
    • 優先順位が安定している期間
    • 外部からのフィードバックの必要性
    • イテレーションのオーバーヘッド
    • 切迫感を感じ始めるまでの時間
 

16章 ベロシティの見積もり

  • ベロシティの見積もり方法としての選択肢で望ましい順に以下がある
    • ベロシティの見積もりを出す前にイテレーションを1回でも実施できるなら迷わずそうする。実績値にまさる見積もりはない
    • 同じメンバーが携わった、今回のプロジェクトに関係のあるプロジェクトでの実績値を使う
  • どのやり方で見積もったにせよ、ベロシティの実績値を使えるようになったら、すぐそちらに切り替える
 

17章 不確実性に備えるバッファの計画

  • バッファの持たせ方でよく使われる方法は、フィーチャバッファとスケジュールバッファの2つである。
    • フィーチャバッファは、プロダクトに対する要求が優先順位づけされていて、その全てが必ず提供されるわけではないと合意できている場合に用意するバッファである。時間が足りなくなったときは、フィーチャバッファにあるフィーチャを削ることでスケジュールを守る
    • スケジュールバッファは、スケジュールに適用するバッファである
 

18章 複数チーム編成プロジェクトの計画づくり

  • アジャイルプロジェクトは、大規模なプロジェクトに対しては、1つのチームを大きくするのではなく、複数の少人数チームを編成することが多い。チーム間で共有できる見積もり基準の確立、ユーザーストーリーの早い段階での詳細化などが必要となる
 

第5部 トラッキングと情報共有

19章 リリース計画のモニタリング

  • リリースバーンダウンチャートは、各イテレーションの開始時点でプロジェクト全体としてストーリーポイントがどれだけ残っているか把握するためのもので、プロジェクトの完了見込みがいつになるかを教えてくれる非常に強力なツールである
 

20章 イテレーション計画のモニタリング

  • タスクボードは、どのタスクが作業中で、どのタスクがサインアップ待ちなのかが一目でわかるツールである。タスクボードの列にはそれぞれラベルをつけておき、作業の進行に応じて対応するタスクカードをチームメンバーが順番に右側の列に動かしていく
 

21章 計画とコミュニケーション

  • 見積もりと計画のコミュニケーションは、正直で頻繁な、双方向のものであるべきである。これはアジャイルな計画とは頻繁に更新されるものであり、フィードバックと新しい知識を繰り返し反映させることで洗練させていくためである
 

第6部 なぜアジャイルな計画づくりがうまくいくのか

  • アジャイルな見積もりと計画づくりのための12のガイドライン
    • 1. チーム全体を巻き込む:見積もりはチーム全体で出すなどチーム全体の参加とコミットメントを引き出す
    • 2. 複数レベルの計画を立てる:リリース計画、イテレーション計画、今日の計画それぞれに狙いがある
    • 3. 大きさの見積もりと期間の見積もりを区別するために別々の見積もり単位を使う:作業の大きさにはストーリーポイント、期間にはベロシティを使うとよい
    • 4. 不確実性はフィーチャか日付のいずれかで表現する
    • 5. 頻繁に計画を見直す:新しいイテレーションを始めるタイミングは、現在のリリース計画を見直すいい機会である
    • 6. 進捗をトラッキングして情報を共有する:プロジェクトの進捗をあらわす手段には、バーンダウンチャートなどの一目でわかるグラフを使うのがベスト
    • 7. 学習することの大切さを受け入れる:新しく得た知識があれば、必ずそれを計画にも反映する
    • 8. フィーチャは適切な大きさで計画する:数イテレーション以内の近い将来に開発予定の機能は、比較的小さなユーザーストーリーに分割する。ユーザーストーリーのサイズは1、2日から10日位までの大きさが一般的である
    • 9. フィーチャを優先順位づけする:フィーチャの価値とコストだけでなく、フィーチャから得られる知識と、フィーチャを開発することで軽減できるリスクも考慮に入れる
    • 10. 現実に即した見積もりと計画を立てる
    • 11. ゆとりを残す:メンバー全員の時間を100%使い切るような計画を立てない
    • 12. 複数チームの連携には「移動する先読み範囲」を使う:チーム間で依存関係が生じるフィーチャについては、ある程度先を見越して、あらかじめ実装するイテレーションを決めておく
 

おわりに

ここまで読んでいただきありがとうございます。
アジャイルの合理的な考え方に共感し、是非一度やってみたいなーという気持ちになりました。
本書では具体例を多く取り入れながら一つ一つ詳しく解説してくれているので、アジャイルに興味を持った方は是非読んでみてください。

次はデータベース設計についての本を読むつもりです。

来週も頑張ります!