Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

DynamoDBについて調べてみたことを書いてみた その3

前回書いた記事「DynamoDBについて調べてみたことを書いてみた その1、その2」の続きの話です。

kodak.hatenablog.com

kodak.hatenablog.com

今回は、いよいよLSIとGSIについての話です。

LSIとGSIとは?

LSIとGSIは、それぞれの正式名称は以下になります。

そう、インデックスなんです!!
ですが、ただのインデックスではありません。これらはインデックスですが、テーブルを複製しています。
何を言っているかわからないと思いますが、LSIから見ていきます。

LSI(ローカル・セカンダリ・インデックス)

DynamoDBの一意となるKey(プライマリーキー)は、Hash、HashとRangeの組み合わせの2つから作ります。
しかし、それでは使いづらい・・・
何故ならテーブル内に、他にも一意になりそうなKey項目や検索条件で使用したい項目があっても、今のままでは指定する事ができないからです。そんなときに使うのがGSIとLSIです。

LSIは、テーブルに対して最初に指定したHashとRangeの組み合わせに対して、もう1つ別のRangeを設定できます。 (ただし、テーブル作成時にHashとRangeの両方を定義した場合に限ります。)
つまり、検索条件やソートしたい項目を追加で1つ選ぶ事ができるのがLSIの魅力です。

実際にテーブルを作成するコマンドを見てみましょう。

aws dynamodb create-table \
    --table-name Music2 \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
        AttributeName=SongWriter,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=1,WriteCapacityUnits=1 \
    --local-secondary-indexes \
        "IndexName=Music-Lsi,
            KeySchema=[
                {AttributeName=Artist,KeyType=HASH},
                {AttributeName=SongWriter,KeyType=RANGE}
            ],Projection={ProjectionType=KEYS_ONLY}"
  • --local-secondary-indexes : LSIを定義する。
  • IndexName : LSIの名前を定義する。
  • KeySchema-[{AttributeName=XXX,KeyType=HASH}] : LSIのHashを定義する。--key-schemaのHASHと同じになる。
  • KeySchema-[{AttributeName=XXX,KeyType=RANGE}] : LSIのHashに対して、新しいRangeを指定する。
  • Projection : インデックスに射影される属性を指定する。

ちなみに、LSIのHashを既存テーブルのHash以外を選ぶと以下のように怒られます。

An error occurred (ValidationException) when calling the CreateTable operation: Local Secondary indices must have the same hash key as the main table

上記で「ただのインデックスではありません。これらはインデックスですが、テーブルを複製します。」と言いました。
LSIは、ProjectionTypeで指定した項目+既存テーブルのHashとRangeを持つ別テーブルを作成します。
それらのテーブルのデータは、既存テーブルのHash毎に格納されます。
図で書くとこんな感じです。

f:id:special-moucom:20190331220857p:plain

なんかインデックスっぽくないですよね(= =;;)

GSI(グローバル・セカンダリ・インデックス)

LSIはHashは変えずに、新しいRangeを追加していました。
HashもRangeも既存テーブルとは異なる項目を設定したい!そんなときに使うのが、GSIです。

テーブルを作成するコマンドを見てみましょう。

aws dynamodb create-table \
    --endpoint-url http://localhost:8000 \
    --table-name Music4 \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
        AttributeName=Label,AttributeType=S \
        AttributeName=SongWriter,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=1,WriteCapacityUnits=1 \
    --global-secondary-indexes \
        "IndexName=Music-Gsi,
            KeySchema=[
                {AttributeName=Label,KeyType=HASH},
                {AttributeName=SongWriter,KeyType=RANGE}
            ],
            Projection={ProjectionType=KEYS_ONLY},
            ProvisionedThroughput={ ReadCapacityUnits=1, WriteCapacityUnits=1 }"
  • --global-secondary-indexes : GSIを定義する。
  • IndexName : GSIの名前を定義する。
  • KeySchema-[{AttributeName=XXX,KeyType=HASH}] : GSIのHashを定義する。--key-schemaのHASHと異なる項目を設定する。
  • KeySchema-[{AttributeName=XXX,KeyType=RANGE}] : GSIのHashに対して、Rangeを指定する。
  • Projection : インデックスに射影される属性を指定する。
  • ProvisionedThroughput : 指定したテーブルのスループットを指定します。(こちらの説明はまた今度)

LSIと書き方はほぼ同じです。とはいえ、GSIで指定するHASHに制限はありません。

LSI同様、インデックスでありながらGSIもテーブルを複製しています。しかし、恐らくデータの格納方法はLSIとの違うように思えます。
LSIは、既存のテーブルのHash毎にデータを格納していましたが、GSIは完全に別テーブル、別Hashを使っているように見えるからです。
図で書くとこんな感じです。

f:id:special-moucom:20190331220934p:plain

GSIで指定するHashですが、これがどこまで一意を気にしないといけないのか・・・私もわかっていません。
ですが、あくまでインデックスなので、既存テーブルのHashを何かしらうまいこと使ってくれているようにも思えます。 ここら辺はもう少し調査が必要ですね。(= =;;)

LSIとGSIの使いどころ

LSIとGSIの使いどころですが、単純にRange=SortKeyと考えると別の項目でソートしたい場合、既存のテーブルに対して、色々な角度からテーブルを参照したい場合(例えば、テーブルに曲名とジャンルの項目がある場合、曲名からテーブルを見たり、ジャンルからテーブルを見たり等)に使えそうです。
調べてみると、LSIよりもGSIの方が使い勝手が良く、GSIをいかに上手く使うのかがDynamoDBのポイントだそうです。

最後に・・・

DynamoDBについて、個人的に調べていた事を3回に渡って書いてみました。
私自身、DynamoDBの使用経験はありません。(少しコマンドで叩いて使ってみた程度です。)
そんな状態で調べた事をずらずらと書いたので、間違った情報もきっと幾つかあると思います。

とはいえ、ブログに書く事で色々と学びになりましたし、整理もできました。結果的にやってよかったと思っています。

現在、LambdaからDBを扱うならDynamoDB一択ですが、もう一つDocumentDB(MongoDB互換)というのがあります。

aws.amazon.com

こちらは東京リージョンにはまだ来ていないのですが、噂ではこちらもLambdaとの相性が良く、DynamoDBの代わりになるDBになる様です。
こちらも東京リージョンにきた時には色々と調べてみたいなぁと思います。

DynamoDBについて調べてみたことを書いてみた その2

前回書いた記事「DynamoDBについて調べてみたことを書いてみた その1」の続きの話です。

kodak.hatenablog.com

今回は、前回書けなかったLSIとGSIについて書こうと思ったのですが、その前に前回の記事の補足を色々と書いていたら意外と濃い内容になってしまったので、今回は補足だけに留めておこうかと思います。

前回のおさらい

前回、HashとRangeという考え方の話をしました。

Hashは、Hash値ごとにデータを分散して格納しているので、一意であることが望ましいカラム
Rangeは、Hashの抽出範囲を決めるため(検索用)のカラム

でした。
じゃあ、HashとRange以外の値はというと・・・?「重要ではない」のです。「重要ではない」この意味は、テーブルを作成するコマンドを見るとわかります。

# dynamodbでテーブルを作成するコマンド
$aws dynamodb create-table \
    --table-name Music \
    --attribute-definitions \
        AttributeName=Artist,AttributeType=S \
        AttributeName=SongTitle,AttributeType=S \
    --key-schema \
        AttributeName=Artist,KeyType=HASH \
        AttributeName=SongTitle,KeyType=RANGE \
    --provisioned-throughput \
        ReadCapacityUnits=1,WriteCapacityUnits=1

create-tableを見てみると、書かれている内容は以下の通り。

・ --table-name : テーブル名を指定します。
・ --key-schema : テーブルのプライマリキーを構成する属性を指定します。プライマリーキーはHash、HashとRangeの組み合わせの2つから作ります。
・ --attribute-definitions : テーブルとインデックスのキースキーマを記述する属性のリストを定義します。多くは、--key-schemaと同じものが記載されるはずです。
・ --provisioned-throughput : 指定したテーブルのスループットを指定します。(こちらの説明はまた今度)

RDBであれば、テーブルを作る時に格納するカラム名を事前にすべて定義する必要がありました。
しかし、DynamoDBは定義しません。定義しないということは、テーブルから見た時にHashとRange以外にどのような値を持つデータが格納されているのかわからないという事になります。
つまりテーブルにとってHashとRange以外は「重要ではない」という事になります。

このあたりのデータに対する扱い方はRDBとかなり変わってくるので興味深いです。 (ちなみに、DynamoDBはRDBでいうカラムをAttributeと呼ぶのですが、この場では言い辛いので引き続きカラムと呼ぶことにします)

Range Key = Sort Key?

Rangeで指定されたカラムは、Range Keyとなります。Hashで指定されたカラムは、Hash Keyです。このRange Keyは、なんと自動でソートしてくれるのです(デフォルト昇順)
試しに以下のようなデータをテーブルに格納してみると、"A"->"Z"->"a"->"z"、"ひらがな"->"漢字"という順で並び替えてくれました。

Artist(Hash) SongTitle(Range)
浜崎あゆみ A
浜崎あゆみ SEASONS
浜崎あゆみ a
浜崎あゆみ evolution
GLAY ここではない、どこかへ
GLAY とまどい
GLAY 生きてく強さ

このRange Keyが自動でソートしてくれる機能は、かなり重要です。というのも、上で書いたとおりDynamoDBはHashとRange以外は、テーブルから見て何が格納されているかわかりません。
ということは、RDBで言うorder byが使えません。order byに代わるのは、このRange Keyのみです。

ソートをプログラムで書くのは、以外と面倒だったりするのでRange Keyを上手くつかわないといけません。

問題

ここで問題です。
以下のようなテーブルがあるとき、何をHashに何をRangeに選びますか? ちなみに、更新日時を指定してデータを取得したいという要件があるとします。

タイトル 更新日 更新時間 ラベル コメント
○○を追加 2019-03-13 23:50:20:10 □□日記 ○○が追加されました、是非御覧ください。
△△を更新 2019-03-14 21:50:40:11 □□スケジュール △△が更新されました、是非御覧ください。
○○を追加 2019-03-14 19:50:35:35 □□日記 ○○が追加されました、是非御覧ください。
△△を更新 2019-03-11 15:50:20:40 □□スケジュール △△が更新されました、是非御覧ください。
○○を追加 2019-03-11 02:50:19:35 □□日記 ○○が追加されました、是非御覧ください。
○○を追加 2019-03-16 05:50:13:35 □□日記 ○○が追加されました、是非御覧ください。
△△を更新 2019-03-16 01:05:30:02 □□スケジュール △△が更新されました、是非御覧ください。

・・・・悩みますよね。

まずは、Rangeを考えます。
「更新日時を指定してデータを取得したいという要件がある」とのことですが、更新日と更新時間が2つのカラムに分かれています。2つのカラムに対して、Rangeを指定するのは不可能なので、この場合「更新日+更新時間」の力技カラム(Number型)を作ります。そして、そのカラムに対してRangeを指定します。

次に、Hashを考えます。
この時、どういった結果が欲しいかを考えます。更新日時を中心に考えるのか、ラベルを中心に考えるのか、それにより結果が変わってきます。

■更新日をHashで考えた時のソート結果

タイトル 更新日(Hash) 更新時間 ラベル コメント 力技カラム(Range)
○○を追加 2019-03-13 23:50:20:10 □□日記 ○○が追加されました、是非御覧ください。 2019031323502010
○○を追加 2019-03-11 02:50:19:35 □□日記 ○○が追加されました、是非御覧ください。 2019031102501935
△△を更新 2019-03-11 15:50:20:40 □□スケジュール △△が更新されました、是非御覧ください。 2019031115502040
○○を追加 2019-03-14 19:50:35:35 □□日記 ○○が追加されました、是非御覧ください。 2019031419503535
△△を更新 2019-03-14 21:50:40:11 □□スケジュール △△が更新されました、是非御覧ください。 2019031421504011
△△を更新 2019-03-16 01:05:30:02 □□スケジュール △△が更新されました、是非御覧ください。 2019031601053002
○○を追加 2019-03-16 05:50:13:35 □□日記 ○○が追加されました、是非御覧ください。 2019031605501335

■ラベルをHashで考えた時のソート結果

タイトル 更新日 更新時間 ラベル(Hash) コメント 力技カラム(Range)
○○を追加 2019-03-11 02:50:19:35 □□日記 ○○が追加されました、是非御覧ください。 2019031102501935
○○を追加 2019-03-13 23:50:20:10 □□日記 ○○が追加されました、是非御覧ください。 2019031323502010
○○を追加 2019-03-14 19:50:35:35 □□日記 ○○が追加されました、是非御覧ください。 2019031419503535
○○を追加 2019-03-16 05:50:13:35 □□日記 ○○が追加されました、是非御覧ください。 2019031605501335
△△を更新 2019-03-11 15:50:20:40 □□スケジュール △△が更新されました、是非御覧ください。 2019031115502040
△△を更新 2019-03-14 21:50:40:11 □□スケジュール △△が更新されました、是非御覧ください。 2019031421504011
△△を更新 2019-03-16 01:05:30:02 □□スケジュール △△が更新されました、是非御覧ください。 2019031601053002

どうでしたでしょうか? RDBと考え方が全然違いますよね。なかなかHashやRangeが決まらないなぁという時は、力技カラムを作ってそれをHashやRangeにする方法も1つです。
DynamoDBってRDBと考え方が全然違うんだなぁという雰囲気を掴んでもらえれば幸いです。

次回こそっLSIとGSIについて書こうと思います。

DynamoDBについて調べてみたことを書いてみた その1

以前「NoSQLについて誤解していたことと学びについて」という記事を書いて、NoSQLへの知識が少し深まったので、引き続き書いてみたいなと思います。

kodak.hatenablog.com

今回はNoSQLの中でも代表的なDynamoDBについて、深掘りたいと思います。

DynamoDBとは?

Amazon DynamoDB(以降、DynamoDB)といいます。AWSで提供しているNoSQLの1つです。DynamoDBの特徴は以下の通り。

  • NoSQL
  • 分散型データベース
  • スケールアウトが容易
  • 結果整合性という考え方を持つ
  • KVS(Key-Value Store)
  • HashとRangeという考え方

なぜDynamoDBって人気なの?

数あるCloudサービスの中で、良く使われているのはAWSだと思います。
そのAWSを使ってサーバーレスにサービスを提供したい!と考えた時、まず考えるのがAWSのLambdaを用いたイベント駆動のサービスだと思います。
しかし、Lambdaはイベントに応じて処理を動かすというだけで、データを格納するストレージ機能はもっていません。データを保存しておくにはデータベースが必要です。データベースといえば、OracleMySQL、PostgresなどのRDBが有名ですが、それらはLambdaと相性が非常に悪いのです。

詳細はこちらの記事を見ていただければと思います。すごく勉強になりました!

www.keisuke69.net

私の理解ですが、OracleMySQL、PostgresなどがLambdaと相性が悪いのは、それらDBがスケールアップしかできなくて、(Lambdaのような)大量の同時接続が発生するケースは、接続制限を設けたり、(DBに繋ぐための)コネクションを再利用しているから。
図にすると、こんな感じ・・・

f:id:special-moucom:20190311011520p:plain

DynamoDBならスケールアウトできるし、そもそも「結果整合性」という考え方なので、データの即時反映は目指しておらず「いつか反映されれば良い」のでコネクションについて深く考えなくて良い。

f:id:special-moucom:20190311011542p:plain

というわけで、AWSを使ってサーバーレスにサービスを提供したい!ならDBの選択はDynamoDB一択なので、人気があるということです。じゃあ、Lambdaと相性の良いRDBはないのか?という話になると思いますが、Amazon Auroraと呼ばれるDBがあり、こちらも人気です。
私は使ったことがないので何とも言えないのですが、大抵の場合はDynamoDBでよかったりするのと、DynamoDBよりもコスト(お金)が掛かるといったところで、どうしてもRDBでないといけない以外は使われないイメージです。

KVSとは?

Key-Value Storeのことです。 KeyとValueを組み合わせた構造でデータを格納する仕組みで、JSONのような構造を思い浮かべるとイメージしやすいかと思います。

HashとRangeという考え方

DBには、データを識別するための一意となるKey(プライマリーキー)が必要です。DynamoDBはそれをHash、HashとRangeの組み合わせの2つから作ります。

Hash

Hashという1カラムを選択することで、そのカラムをプライマリーキーとして扱います。
なので、そのカラムは一意でなくてはならい・・・のですが、名前はプライマリーキーとは書いていないので、別に一意にしなきゃいけないルールはありません。Hashは、いわゆるHash値(データを特定の計算方法によって出力する値)のことです。そうなんです。DynamoDBはHash値ごとにデータを分散して格納しているんです。
図で書くとこんな感じで、hashの「bb」が同じところに保存されます。

f:id:special-moucom:20190311012132p:plain

データが分散すればするほど、DBはデータを探す手間が省けるので効率が良くなります。逆にを同値が多いカラムをHashにしてしまうと、DBはデータを探す手間がかかり効率が悪くなります。つまり「DBが遅い」「DBが落ちる」等の事象が発生します。

DynamoDBの設計は難しいと言われるのは、こういった裏の仕組みを知らないといけないからでしょうね(- - ;;)。

HashとRangeの組み合わせ

Range、こちらはHashの抽出範囲を決めるため(検索用)のカラムです。
Hashは一意であることが多いので、このカラムを使って値の抽出範囲を広げることができます。さきほどのHashとRangeを組み合わせて、そのカラムをプライマリーキーとして扱えます。Hashをどうしても一意にできない場合やGSIを使用したい場合に使います。
ここで注意したいのは、Hashの役割は変わらないということです。「Hashをどうしても一意にできない場合」と書きましたが、だからといってhashの値がすべて同値だと、やはり効率が悪くなります。

f:id:special-moucom:20190311012142p:plain

まとめ

というわけで、DynamoDBについて調べたことを書いてみました。LSIやGSIのことも書けてないので、それはまた別の機会に書きたいと思います。いやぁ、やっぱりこうやって自分が調べた事を記事にすると、自身も考えも纏まって非常に良いですね。
記事にするのに時間がかかりますが・・・(T T)

さて、DynamoDBについては、以下記事のシリーズが丁寧にまとまっていたので、DynamoDBについて知りたい方はこちらの記事を読むことをオススメします。すごく参考になると思います。

dev.classmethod.jp

書籍「管理ゼロで成果はあがる「見直す・なくす・やめる」で組織を変えよう」を読んで、これはプログラマの方にもオススメの本だと確信した話

前回のブログに引き続いて、「何か図書館に置きたい本ない?」と会社からアンケートが回ってきた時に、もう1冊読みたいと思って希望していた本がありました。
それがこれです。

攻めたタイトルの本だったので、てっきり希望は却下されるだろうと思っていたのですが、すんなり図書館に置いてもらえたので、さっそく手にとって読んでみました。

かんたんに書籍のご紹介

この本を書かれた倉貫義人さん(以降、倉貫さん)は、株式会社ソニックガーデンというIT系の受託開発を行っている会社のCEOです。 株式会社ソニックガーデンといえば「納品のない受託開発」や社員全員がリモート開発をされており、物理的なオフィスがない事で有名ですね。
また、「プログラマを一生の仕事にする」ことを会社のビジョンとして掲げており、CEO含めて全員がプログラマの会社です。
普通の会社には当たり前に存在する営業や人事をする人がいない中で、どのようにして会社経営をされているのか、そんな会社経営にした理由や考え方を纏めている本です。

この本を読みたいと思ったきっかけ

元々、ソニックガーデンさんの存在は知っており、CEOの倉貫さんのブログやインタビュー記事は、ちょくちょく拝見しておりました。 その内容がとても面白かったこと、そして何より記事がプログラマ目線で書かれていたので、本書が出版された時は絶対におもしろいだろうと思っていました。

実際に本書が出版された時は、個人的に購入しようと思っていたのですが、社内の図書館に置いてもらえるなら社内で共有できるので、そちらの方が良いという結論に至りました。(正直、図書館に置くのは却下されると思っていたので、置いてもらえた時は驚きました)

経営者・管理職をやられている方だけでなくプログラマにもオススメ

本のタイトルから経営者・管理職をされている方向けの内容と思ってしまいますが、実はプログラマ向けに書かれている内容も多々ありました。
この本は以下3段階に分けて書かれているのですが、どれも主語を絞っていないんですよね。

 ・第一部 生産的に働く
 ・第二部 自律的に働く
 ・第三部 独創的に働く

なので、プログラマとして生産的、自律的、独創的な働き方についても書かれおり、(転職前は)管理職、(転職後は)プログラマの両方を経験している身としてはとても勉強になりました。

第一部 生産的に働く

第一部は、生産的に働くために仕事のやり方を見直しましょう!という事が書かれていた。
どちらかというと現職のプログラマに向けたメッセージが多い印象を受けた。

-「ふりかえり」

いきなり仕事を始めるのではなく、まずは考えること。目的(ゴール)を明確にして「タスク」に落とし込んでから仕事をしましょう。
これ自体は(マネジメントの研修等でも)よく耳にする言葉です。
しかし、倉貫さんはこれに加えて「ふりかえり」をやりましょう!と伝えている。

この「ふりかえり」は、個人で実践されている人はいても、チームで実践されている人は少ないと思う・・・・
(私は個人でも、チームでも実践できていませんが・・・orz)

「ふりかえり」は「KPT」と呼ばれる方法を使い、Keep(よかったこと)、Problem(悪かったこと)を洗い出して、次に繋げるTry(次に試すこと)を決める。
これを週1で継続することで「自分たちがチームを変えていく!成長させていく!」という意識が根付くとのこと。

これは個人でも、チームでも実践すると「効果が期待できそう」だと感じた。

- 報連相ではなく、雑相!

会社に入って間もないころは、よく「報連相」を耳にしたが、倉貫さんは「雑相」も大事だと伝えている。
「雑相」つまり、雑談と相談のこと。

これは、なんとなくわかる気がする。私も上司と雑談をしていると、自然と相談になっていたりする事が稀にあったりする。

ここでは、雑談が大事であるということ。人から雑談してもらえる雰囲気を作ることが大事だという事を学んだ。その雑談が気軽にできるようにしていくには、Slack等のツールを導入するのが良いとも書かれていた。

第二部 自律的に働く

第二部は、自律的に働くために、(人を縛る)変なルールや決まりをなくしていこう!という事が書かれていた。
こちらは経営者・管理職に向けたメッセージが多い印象を受けた。

- 読んでて「あるある!」

個人的にツボだったのは「評価をなくす」の部分、「あるある!」を感じた。
(前職では)この本で問題視されている「評価」の方法とまったく同じ事をしていたので、すごく共感できた。

いわゆる、年初・半期初に目標を立てて、年末・半期末に「評価」する方法のこと。
本書でも問題視しているが、この方法だと、個人が目標を低すぎず高すぎずの変な按配で意識的に目標を立ててしまったり、評価期間が長くてそもそも目標が変わってしまったり・・・という問題がおきてしまう。

(前職では)まさにこの問題がおきていて、多くの人が、年末・半期末に目標と評価を一度に書くという、意味不明なことをしていた。

ソニックガーデンさんは、この対応として「評価」をなくして「給料はほぼ一律」、「すりあわせ」を取り入れるといった方法を行っている。

- セルフマネジメントできるエンジニアになろう

倉貫さんは「成果をあげるために自分で考え、自分が責任をとれる範囲で、自分で決める」これがセルフマネジメントだと伝えている。
これがすごく心に響いた。

とくに「自分で決める」という部分!
「お客さんの言われた通りに・・・」「お客さんの許可・確認をして・・・」とやたら言う上司がいたのを思い出しました。こんな言われたままやるだけでは、良いチーム・プログラマになれない。と私も思う。

受託脳ではなく、提案脳になろうとも書かれており、プロ意識を持とうというメッセージが凄く伝わった。

第三部 独創的に働く

第三部は、独創的に働くために常識や習慣に従うことをやめよう!という事が書かれていた。
こちらも経営者・管理職に向けたメッセージが多い印象を受けた。

ここでは、ソニックガーデンさん自身が常識や習慣に従うことを止めた理由、止めた結果が書かれている。
この内容は是非、本書を手にとって読んで欲しい!!

最後に・・・

ソニックガーデンさんの会社の運営方法は、とても先進的です。
でもそれは、会社(倉貫さん)が人との繋がりを大切にして、個人の考えを尊重している結果なのだと感じました。

多くの会社が、会社を大きくしたい。事業を成功させたい。だから良い人を集めよう。という「会社・事業第一」の考えだけど、ソニックガーデンさんはそうではなく、個人で本を出したいなら応援しよう、海外に住みながら働きたいなら会社での働き方を変えよう。という「個人の尊重を第一」の考えなのだと、その結果なのだと感じました。

また、私は将来「強いエンジニアになりたい」という、定義がしっかりと定まっていないざっくりした目標を持っていました。本書を読んで、私のイメージする「強いエンジニア像」の定義みたいなものが、なんとなく見えてきた気がします。

具体的には「技術だけを追い求めるエンジニアではなく、当事者意識をもって自分で考えて行動・意思決定できるエンジニア」かなと。

その目標に向かって、まずは「考えること」「目標設定してタスクばらしをすること」から始めていきたいと思います。

書籍「テスト駆動開発」を読んで、これからはテスト書こうと思えた話

うちの会社には、小さな図書館があります。
ある日「何か図書館に置きたい本ない?」と会社からアンケートが回ってきました。
以前から、t_wadaさんの書籍「テスト駆動開発」が読みたいと思っていたので、希望したらすんなり図書館に置いてもらえたので、さっそく手にとって読んでみました。

ちなみに、以下の本です。

テスト駆動開発

テスト駆動開発

後悔? 写経しなかった・・・

いきなり後悔からです。
写経はしていません。借りた本なので写経する時間はありませんでした。

でも、個人的には写経しなくて良かったとも感じています。
この本は、写経するだけでも少し難しそうな感じがしたので、写経に時間と手間をかけるよりも、まずは1回さらっと読んでみてテスト駆動開発(以降、TDD)について理解を深める事が大事だと思いました。

なので、1回さらっと読んでみて、2回目で写経するのが個人的に良いと思いました。(私はまだ写経してないですが・・・)

TDDはテスト技法ではない!

TDDでよく言われている言葉です。
とは言え、私はこの言葉の意味をちゃんと理解していませんでした。

本にも書いてありましたが、TDDは自分でテストコードを書いてテストするので第三者からの観点がありません。
また、パフォーマンスのテスト等もやりません。
なので、コードレビューもテストも別で実施する必要がある。ここは私も「ぇ、そうなの?」と思わされました。

じゃあTDDとは何なのか・・・
私は、てっきりテストを事前にやるからテスト漏れを未然に防ぐことができ、品質の高いプロダクトができる技法かと思っていました。

でも、この本は「TDDを行う=バグゼロにはならない!(そんな魔法ではない。)TDDをするからといって、テストエンジニアが不要になるわけではない。」と書いてあった。

TDDはコードを書く技法

この本を読んで、TDDはコード書く技法だとわかった。
TDDは以下の流れでコードを書いていくのだが、ポイントは3.のリファクタリングにある。

  1. テストを書く
  2. コードを書く
  3. リファクタリングする

テストをして、ちゃんと動く状態を保ちながらコードを書いて、リファクタリングで綺麗にしていく。 そういったコード書く技法だとわかった。

本にも「綺麗なコードと動くコードを同時に満たすのは難しい、まずは、動くコードにして、綺麗なコードを心がけよう」と書いてあった。

TDDは必ずしも必要ではない?

必要ではないそうです。
TDDはプロダクトに必ずしも影響を与えるものではないし、本来のテストも別で実施する必要があるので、TDDが絶対に必要ということはないそうです。

本にも「テストをしながら開発をするのであれば、プログラマが書くコード量は2倍になり、それだけ時間が掛かるのでメリットは感じ辛いだろう」と書いてありました。

では何故TDDが流行るのか?

本にも書いてありましたがTDDはプログラマにとってメリットがあるんですね。
(t_wadaさんもこの本で「テストは質をあげない。質をあげるのはプログラミングだ!」と仰っておりました)

  • テストを書く習慣ができる。
  • 書くコード量は2倍になるので、よりコードと向き合えるようになる。つまり、リファクタリングに目を向けられるようになる。
  • TDDはスキルなので、アピールできる!

これらに加えて、最近は本でもTDDを使った説明や写経本が増えているように思えます。
なので、TDDを知っておかないと(テストの書き方を知っておかないと)せっかく読みたい本でもTDDがあって読めなかったり、避けたり、挫折したりしてしまうかもしれません。

なので、私もTDD頑張ろうと思います!

最後に・・・そういえば、t_wadaさんと言えば・・・

以下のAAが有名ですね。

f:id:special-moucom:20190221232115p:plain

この本を読んでも、何故ライオンなのか?何故このAAが産まれたのか・・・わかるかなぁと思ったのですが、わかりませんでした。
残念。