BASE開発チームブログ

Eコマースプラットフォーム「BASE」( https://thebase.in )の開発チームによるブログです。開発メンバー積極募集中! https://www.wantedly.com/companies/base/projects

テストを書くモチベーションを上げるための、カバレッジレポート活用方法

f:id:okinaka:20181210121202j:plain
BASE Advent Calendar 2018 (13日目)

この記事は、「BASE Advent Calendar 2018」の13日目の記事です。

devblog.thebase.in

Backend Engineerの沖中 (@okinaka) です。

読者のみなさんはテストを書いてますか?テストが面倒くさいとか思ってませんか?(私はたまにあります)
そんな時、モチベーションをあげるには、どのような工夫をしていますか?

私の場合、カバレッジ計測の結果のレポートがとても役に立っています。 レポートを眺めると、視覚的に

  • 「どの行が実行された」とか
  • 「カバレッジ率が◯%」だとか
  • 「ここ複雑だけどテストがないクラスがあるよ」など、

いろいろ気づきがあります。

「ここマズイな、テスト書いて確認しなくちゃ!」という気持ちになるのでとても重宝しています。

とてもいいツールだと思うのですが、残念ながら BASE社内でもまだ十分に活用されていないのが現状です。ですので、この記事をきっかけに、広めていければいいのではないかと期待しています!

現状ではカバレッジレポート出力が時間がかかる問題があるのですが、今後、自動生成する仕組みを用意できればと考えています。

カバレッジレポートについて

BASEでは、主にCakePHPでサービスが構築されており、ユニットテストも、若干手を加えていますが基本的にはCakePHPに用意された仕組みを利用しています。カバレッジレポートは、その機能を利用して生成しています。

カバレッジについての簡単な説明は、CakePHP クックブックをご覧ください。
(内部的には PHPUnit を利用しています。詳細は こちら

カバレッジレポートには出力形式がいくつかあるのですが、今回はモチベーションアップが目的なので、人が見てわかりやすいHTML出力を紹介します。

出力されるHTMLページは大きく分けて3つに分類されます。

各ディレクトリ内のファイル一覧 (index.html)

  • ファイル毎の大まかなカバレッジ状況を一覧で確認できるページ*1

f:id:okinaka:20181210123856j:plain
ファイル一覧(index.html)

各ファイルのカバレッジ詳細 (PHPファイル名.html)

  • どの関数・行がテストされたかなど詳細を確認できるページ
  • 次にどんなテストが必要かを考える際に役立ちます

f:id:okinaka:20181210124020j:plain
カバレッジ詳細(PHPファイル名.html)

ダッシュボード (dashboard.html)

  • 以下のカバレッジ状況を俯瞰的に確認できるページ
    • クラス・メソッドのカバレッジ率 (Coverage)
    • コードの複雑度 (Complexity) の分布図
    • カバレッジ率の低い順のクラス・メソッド一覧
    • リスク (CRAP値) の高い順のクラス・メソッド一覧
  • 全体の状況を把握したり、次にどのファイルをテストすべきかをざっと見るのに便利!

f:id:okinaka:20181210124152j:plain
ダッシュボード(dashboard.html)

テスト作成とカバレッジレポート出力

では、実際にレポートを出力して内容を見てみましょう。

まず最初に、とあるメソッドに対してテストを1つ書いてみました。

<?php
    public function testView()
    {
        // テスト対象を実行
        $this->testAction('/posts/view/1', ['method' => 'get', 'return' => 'contents']);
        
        // とりあえず、ステータスコードの確認
        $this->assertSame(200, $this->controller->response->statusCode());
        
        // その他、なんらかの結果の確認...
    }

この時点で、カバレッジレポートを出力してみます。レポートを見ると、どうやら一部実行されていない行があるようです。 (注:緑の部分がテストされた行で、赤い部分が未テストな行です。赤い部分をなんとか消したくて、ウズウズしてきますね!)

f:id:okinaka:20181210124316j:plain
カバレッジ詳細(テスト1回目)

未テストだった行を確認してみると、$id が未指定 (null) だった場合と、 データーベースに未登録な $id だった場合の処理がテストされてないようです。 このレポートを受けてテストケースを追加してみます。

<?php
    /**
     * @expectedException NotFoundException
     * @expectedExceptionMessage Invalid post
     */
    public function testViewで、IDが未指定だった場合は例外発生()
    {
        $this->testAction('/posts/view/', ['method' => 'get', 'return' => 'contents']);
    }

    /**
     * @expectedException NotFoundException
     * @expectedExceptionMessage Invalid post
     */
    public function testViewで、未登録なIDを指定した場合は例外発生()
    {
        $this->testAction('/posts/view/999', ['method' => 'get', 'return' => 'contents']);
    }

結果がこれ。

f:id:okinaka:20181210124408j:plain
カバレッジ詳細(テスト2回目)

やりました!赤かったところが全部緑色に!これで安心です。

ここで、注意点があります。全部緑色になって喜んでいましたが、緑色の行を増やすよりもむしろテストの内容の方が重要です。 たとえテストが実行されたとしても、ちゃんと動作を確認していなければ意味がありません。あくまで、モチベーションを高め、テスト状況を確認するためのツールと捉えていただければと思います。

明日はデザイナーの森さんです!お楽しみに!

*1:注: CakePHP 公式のクックブックのチュートリアル を元に、独自のテストを実行した結果を表示しています。

BASEがもっと好きになる。鶴岡さん観察日記

f:id:aiyoneda:20181212152057j:plain

この記事は、「BASE Advent Calendar 2018」の12日目の記事です。

devblog.thebase.in

こんにちは、BASE BANKインターンの かわごえ(@heart_breakers2)です。

今回は少し趣向を変えて、「鶴岡さん観察日記」と題して、BASE 代表取締役CEOおよびBASE BANK 代表取締役CEOである鶴岡の普段の様子をイラストを交えてカジュアルに伝えていきたいと思います。
(みなさんにもカジュアルな雰囲気で読んでいただきたいので、記事内ではあえて「鶴岡さん」と表記しています。)

私がインターンとしてBASE BANKにジョインし、鶴岡さんのななめ前の席に配属されてから半年が経ちました。
みなさんがきっと知らない鶴岡さんの素顔や、BASEの好きなところをまとめてみました。
この記事を読んでいただき鶴岡さんやBASEに興味を持っていただけると嬉しいです。

はじめに

みなさんは、BASE代表の鶴岡さんをご存知ですか?

BASEが提供するネットショップ作成サービス「BASE」は、「お母さんも使える」をコンセプトとしたネットショップを作成できるサービスで、現在は60万人を超えるオーナーズに利用されています。

鶴岡さんはBASEの創業者。
Forbes JAPANが発表した「日本の起業家ランキング2019」で3位に選出された、日本で最も注目されている起業家の一人です。

「60万ショップも使っているサービスを作っているんだ!すごい!」
「Forbesでも注目されているんだ!すごい!」
と思った方もいるのではないでしょうか。

私から見た鶴岡さんは、傾聴力と本質を見抜く力が圧倒的に高く、どんな人でも一緒にいて心地よい存在で社内外にファンが多いようです。

しかし、鶴岡さんが遠い存在と思われてしまっているのか、↓のようなツイートにだれもツッコめない状況になっているような気がします。

この記事では、社内での鶴岡さんはどのような様子なのか?何を大切にして事業を進めているのか?
BASEの素敵な制度などもご紹介しつつ、鶴岡さんにまだお会いしたことがない方でも身近に感じていただけるよう、イラストと写真で紹介していきます💫

鶴岡さん観察日記

AM 11:00 

Be Hopefulキャンディー

鶴岡さんの朝は、たいてい午前11時のミーティングで始まります。

鶴岡さんはミーティング中どんな感じなの?と気になる方も多いのではないでしょうか。
社内のミーティングの様子を覗いてみましょう。 f:id:aiyoneda:20181212103119j:plain

鶴岡さんとの社内ミーティングは社長室で行われることが多く、鶴岡さんが座る席の近くにはBe Hopefulキャンディーが入ったガラス瓶が置かれています。

ミーティングではキャンディーを手に取り頬張っている鶴岡さんですが、発言はいつも本質的で、

  • 「オーナーズのためになるどうか」
  • 「オーナーズにとってわかりやすいかどうか」

をいつも大切にしているので、私たちもどのような判断をすべきかがクリアになります。

ちなみに、BASEの行動指針

  • Be Hopeful
  • Move Fast
  • Speak Openly

の3つで、どれも欠かせない重要な指針となっています。

f:id:aiyoneda:20181212104221j:plain

実際のBe Hopefulキャンディー。
行動指針の浸透のために作られたもので、キャンディーの中に"Be Hopeful"と書かれていてかわいいです。
キャンディーの色は、「BASE」のサービスロゴであるティピのマルチカラーを使用していて、社内のいたるところに置いてあります。

PM 0:30 

みんなの食堂

先日からBASEでは、いわゆる社員食堂のサービスが毎週水曜日に提供されています。

鶴岡さんも毎週この社食を利用していて、メンバーと楽しく会話しながらランチをしています!

(鶴岡さんの写真は撮り忘れちゃいましたが、みなさんが食堂を楽しんでいる様子です💕)

現在は30食限定でいつもすぐに売り切れてしまうのですが、500円で定食を食べることができます!!
(BASEは37階にあるので、ランチにいくにも時間がかかってしまうのです)

ココロータス

別の日の様子です。
鶴岡さんはお昼頃になると、定期的に、大好きな神宮司さん(執行役員/Product Manager)にこう語りかけます。 f:id:heart_breakers2:20181212002130j:plain

ココロータスとは、アジア料理を中心に、多国籍のランチを提供するキッチンカーです。またココロータスは、お支払いアプリ「PAY ID」の加盟店で、スマホでQRコード決済が可能なのでお財布を持たなくてもランチを買うことができます。

f:id:heart_breakers2:20181212002201j:plain

メニューが提供されるのを今か今かと待ちわびているようです。

ココロータスのメニューはどれもボリューミーかつ1000円以内で注文できます。企業の社長はいつも豪華な食事をしているというイメージの方もいらっしゃるかもしれませんが、鶴岡さんのランチはいたって庶民的なんです。

ココロータスのキッチンカーは現在、江戸川橋と六本木三丁目で販売を行っています。六本木周辺に勤務されている方はぜひチェックしてみてくださいね!

PM 3:00 

カップスープ

ある日出社すると、隣の机に大量のカップスープが置かれていました。

f:id:heart_breakers2:20181212002430j:plain

置いたのはもちろん鶴岡さん。

f:id:heart_breakers2:20181212002459j:plain とのことだったので、3時のおやつにたまごスープをいただきました。

この時は特に何かのお祝いやイベント事があったわけではないですが、特に理由がなくともさらっとメンバーに差し入れをする様子を見て鶴岡さんの優しさや心遣いを感じました。まだ食べきれていないほど、大量に購入されていました!

ちなみに、鶴岡さんが好きなのはコーンポタージュ。

PM 4:00 

「順調?」

夕方になると、近くにいる人を中心に「順調?」と話しかけるのが鶴岡さんの癖です。
「え!?社長に進捗確認されるとかプレッシャー!!」と感じる方もいるのではないでしょうか。

でもBASEでは違います。

f:id:heart_breakers2:20181212002532j:plain

私から見ると、鶴岡さんの「順調?」という発言はメンバーにプレッシャーをかけたいという意図ではなく、「困ったことがあったらいつでも聞いて大丈夫だよ」という心配りなのではないかと思います。

なので、鶴岡さんに「順調?」と聞かれて正直に答えないメリットはありません。順調ならそう答えればいいし、何か詰まっている点があるなら打ち明けた方がよいです。
私自身も実際にこの言葉をかけられて、「ユーザーからの反応があまりなくて、次の施策をどうするか悩んでます!」と相談したことがあります。

なぜなら先ほども書きましたが、鶴岡さんは傾聴力が優れていて、本質的なことを見抜く力が高く、私たちの想像を超えるようなフィードバックをしてくれるからです。

BASEの行動指針に「Speak Openly」とあるように、たとえ物事が順調に進んでいない場合でも、正直に話すことで鶴岡さんから的確なフィードバックを得られるため本質を見失わずにプロダクトを作り続けることができます。

f:id:aiyoneda:20181212104632j:plain
お気に入りのゴジラをつかみながら喋る鶴岡さん

PM 5:00 

ジャック・ドーシー氏

f:id:heart_breakers2:20181212000839j:plain 鶴岡さんが12/3に日経BP社によって行われたイベント「スモールビジネス新潮流 「ポスト2020」を見据えて」に登壇が決まった時の話です。

テーマは「スモールビジネスが秘める可能性と未来」について。Twitter、Squareの創業者であるジャックドーシー氏も参加するセッションです。

中小企業や個人で活動しているオーナーズをどのような方法で応援できるかについて、鶴岡さんの考えやBASEの取り組みを話したそうです。当日の様子が気になる方はぜひ、Twitterで「#ポスト2020」と調べてみてください!

ちなみに鶴岡さんはかねてからジャックドーシー氏の大ファンで、このイベントでの登壇が決まったときは本当に嬉しそうでした。

(鶴岡さんの目がキラキラしてます!!)

おわりに

いかがでしたか。
鶴岡さんの普段の様子が伝わるように意識して書き上げたので、鶴岡さんの温かい人柄、飾らない素直な性格、そしてBASEの良さが伝わっていると嬉しいです。

明日は、沖中さんがカバレッジレポートについて書きます!

BASE株式会社を6年間経営して感じた学び

f:id:aiyoneda:20181210175321j:plain
先日の締め会の様子

これは「BASE Advent Calendar」11日目の記事です。

devblog.thebase.in

こんにちは。BASEで代表をしている鶴岡(@0Q7)です。
11日目の記事を担当しています。
ある日、Slackでアドベントカレンダーを書く人を募集していたので、調子に乗りそれとなく書く予定にしていたら、書く内容が全く思い付かず悩みすぎたので今はすごく後悔しています。

本日12/11はBASEの設立記念日で、6年が経ちました。早いような遅いような。
f:id:aiyoneda:20181210175454j:plain
ついこの前までは「今日のGMVは100万円は行きたい、そしていつかは500万くらいはいけるようなサービスにしたい。」なんて思いながら毎日帰宅していた気がしますが、その目標から桁が2つくらいは増えたので少しは成長できてるのかなと思います。

ただ何かを成し遂げたわけではないので昔話をしたいわけでもなく、とはいえエモくビジョンの話をするのもなんなので、この6年で実際に感じた学びを書こうと思います。
内容は個人的な主観ですが、誰かの役に立てれば嬉しいです。

殆どの戦いは負けても良い

社会人になって一番の学びかもしれないですが、殆どの戦いには負けても大丈夫なんだなと思いました。 戦いとは、議論や意思決定のことを指していますが、最終的に成し遂げたい目標があったときに、その途中で訪れる論点を全て自分の思い通りにする必要もないんだなと。全ての勝負に勝とうとするにはあまりにも今の人生では短いので、全部の駒を取る事が勝利なのではなく、王将を取る事が勝利なのだとあらゆる場面でゲームをしっかり理解する能力を磨きたいものです。そして王将だけは必ず取りましょう。

感情とは上手く付き合いたい

特に怒りという感情とは上手く付き合った方がいいかなと思いました。 怒りという感情を露わにする事が、物事を最短で進めるための手段になる事は殆どないです。自分の思う通りにしたければまず感情をコントロールできる人間になりたいです。

プロダクトが全て

自分たちが作っているプロダクトが全てを癒してくれます。学歴も地位も立場も関係ないです。最高のプロダクトを作ったチームが一番かっこいいです。「BASE」を使ってくれている60万のショップをみてもそう思います。最高のプロダクトを作ることが出来れば市場が評価してくれます。世の中にあった方がいいプロダクトは必ず成功すると思いますが、タイミングだけが変数です。諦めずチームで最高のプロダクトを作りましょう。

インプットは難しい

自分に合っていない情報のインプットがあると無駄な時間を使ってしまう事があります。情報がこれだけ溢れている昨今において、自分に適している情報はすごく少ないです。Twitterで流れてくる情報は自分のフェーズには早かったりしてほぼ役に立たないなと感じます。世の中で起きている事実だけを把握し、自ら考え自分が思うままに行動するのが一番かなと思います。

評論家にはなりたくない

評論するよりされる側の方がかっこいい!というのも勿論ありますが、これは評論家を批判してるわけではなく、自分のメンタルを保つためにあまりオススメしません。自分を追い込むことになる言動はなるべく慎みたいなと思います。

テクノロジーには超楽観的に

テクノロジーがあらゆるものを便利にしていきます。プラットフォームがあらゆるリスクを巻き取っていきます。今不便だと感じる事は全て解決されるんだろうなと感じます。そうやって訪れる未来を幸せと呼ぶのだと信じています。

徳を積む

そもそも徳が何かも分かっていないのと、どうやったら徳を積めるのか僕もよくまだ分かっていないですが、お金では買えないものである事は確かです。徳が高い人は凄いなと思います。日々の言動や所作を周りの方々に見ていただいて、自ずと積まれていくものだと思うので、常日頃から意識して生きていきたいです。必ずその徳に助けられる日が訪れると思います。

パッと思いつくところだと、こんな感じでしょうか。
こういうのを書くタイプでは無いのですごく疲れました。。。また黙々とプロダクト作りに励もうと思います。

普段はオーナーズの為にEC・金融・決済領域でプロダクトを作っています。
もっと話聞いてみたい!BASEってどんな会社なの!会社に遊びに行ってみたい!と思っていただける方がいらっしゃればぜひメッセをいただければと思います。

明日はBASE BANKインターンのマリーちゃんです。 ではまた。

初めてでも実践できる、挫折しないテックブログ運営~半年間更新0→30本公開しました~

f:id:aiyoneda:20181210122823j:plain

これは「BASE Advent Calendar」10日目の記事です。

devblog.thebase.in

こんにちは。BASEで採用広報を担当している米田(@AiYoneda)です。普段はL'Arc-en-CielのHYDEさんの追っかけをしていて、来週にはきっと東京ドームでその御姿を拝んでいることでしょう・・・

さて、HYDEさんの話は置いておいて、私はテックブログこと「BASE開発チームブログ」の編集部として運営に関わっています。今回は、約8ヵ月続けてきたこの「BASE開発チームブログ」の運営についてのノウハウを余すことなく書いていこうと思います。

テックブログはエンジニア・デザイナー組織のプレゼンス向上や採用に効果があるなどと聞いているけど、なかなかうまく運営できていないという方もいらっしゃるかと思います。そういった方にこちらを読んでいただいて少しでも参考になれば幸いです。

テックブログって本当に効果あるの?約8ヵ月間、編集部として運営を続けてきた効果、成果

BASEでは2018年4月にテックブログ編集部を作り、以降テックブログの運営を担っています。下記は編集部が立ち上がって以降の効果や成果について記載したものになります。

公開記事数がめちゃくちゃ増えて30本以上公開できた

2017年:8本

2018年4月以降:31本!
(このAdvent Calendarで今年あと15本公開予定です!)

2017年は半年くらい更新していない期間もあり、かなりさみしい感じでしたが、2018年4月以降は月2本以上の更新ペースを維持できています。またこの数字はむやみに増やしたわけではなく、ひとつひとつの記事の内容やクオリティは一定に保った上での成果です(実際に記事を読んでいただければわかると思います)。

執筆に関わったメンバーの数ですと、このアドベントカレンダーを含めると約30名のメンバーに執筆してもらうことができました。またブログの読者数(はてなブログの機能で購読していただいている読者の数)は約3倍になりました。

イベント、勉強会での発表機会ができた

  • 大規模Webサービスの開発にせまる「BASE Geek Night #1」

base.connpass.com

  • レガシーコード改革!UT/CIでWebサービスの技術的負債を解消する取り組み

base.connpass.com

テックブログで書いてもらったネタをプレゼン形式にして勉強会やmeetupで発表してもらうことができました。上記は実際に開催したイベントです。中にはこのイベントで「人生で初めてLTをやった」というメンバーの声もあり、外部での発表機会の創出につながりました。

採用面談、面接で「テックブログを見てます!」との声が増えた

正確に数値を計測してはいないんですが、採用候補者とのカジュアル面談や面接を担当するメンバーより、候補者の方から「テックブログ見てます」と言っていただけることが明らかに増えたとのことです。

何より、このAdvent Calendarを実施できた!

日々の運営の積み重ねが実ったのか、2018年はBASEで初のアドベントカレンダーを開催することができました。

11月末に編集長がSlackに下記のように投稿したところ、

f:id:aiyoneda:20181210110059p:plain

これから数時間後…

f:id:aiyoneda:20181210110150p:plain

次々とメンバーが手を挙げてくれて、あっという間に25枠がすべて埋まりました…この怒涛の投稿の様子には正直かなり感動しました。

しかもアドベントカレンダーの開始は12/1、この投稿は11/28とかなりタイトな依頼だったのにメンバーが次々と手を挙げてくれて、BASEの行動指針の一つである「Move Fast」を体現していてすばらしいです。

テックブログの運営で挫折しないためのTips

ここからは実際の運営のTipsを書いていきます。

テックブログの運営でネックなのは、運営担当者自身が人事など現場とは別部署に在籍していたり、入社したばかりという方や年上の方が多い方の場合、周りのメンバーをうまく巻き込めるか、途中で挫折しないか不安だという部分ではないでしょうか。私自身も入社してすぐの、まだメンバーの顔も覚えきれていないような状態で編集部として運営に携わるようになり、かつ前職とは業界や職種も違う状況で初挑戦なことばかりでした。

そんな私でも実行できたTipsですので、特に人事や広報、若手社員の方に試していただけると嬉しいです。

テックブログ運営の成功体験をもつメンバーを運営メンバーに入れる

このメリットは下記の2つだと考えています。

  • 運営ノウハウを転用できる
  • エバンジェリストとして運用のモチベーションを保ってくれる

いきなりテックブログの運営経験がない私が運営を始めてもスベるのは目に見えています。なのでそういう時には素直に成功体験を持つメンバーから運営ノウハウを教えてもらうのが得策だと思います。

また、テックブログ運営の成功体験のある人物とともに運用していくことで、自らのモチベーションを保つことができ、運用中の挫折を回避することができます。自分自身に成功体験がないと運営していく中でどうしても「これは本当に効果があるのだろうか?」、「現場メンバーには迷惑ではないか」と疑心暗鬼になってしまうこともあるのですが、成功体験のあるメンバーはそのような不安を解消してくれる心強い存在で、「Be Hopeful」に運営を続けることができます。

サポート体制を作る

BASEのテックブログでは、現在編集部が中心となり運営をしています。

編集部が行っているのは下記です。

  • 月1の編集会議でのネタ出しと、予備も含めてその月に公開したい記事を決める
  • 該当のメンバーに執筆依頼
  • 記事チェック(編集やタイトル案の相談など)
  • 画像の作成・撮影のサポート
  • 執筆マニュアルのメンテナンス

f:id:aiyoneda:20181210114323p:plain
記事案の管理はスプレッドシートで行っています。「常設」がいわゆる予備記事です。

他の企業では、テックブログは書きたい人が書きたいときに自由に記事を公開するという運営方法を取っている場合もあるかと思います。もちろんBASEの場合も「このイベントで登壇したからその内容をブログ記事にしたい」、「こんな取り組みをやってみたんだけど、ブログネタとしてどう?」といった流れで記事を書いてもらうことはあります。

運営方法は様々だと思いますが、編集部が主導する体制を作ることのメリットは下記だと考えています。

  • 投稿ペースを維持できる
  • 社内のいろんな人に書いてもらいやすい
  • 記事のテイストを一定に保てるため読者が読みやすい

まず投稿ペースに関してです。現在は月に2本は必ず公開するという方針の下、編集部で予備も含めて公開したい記事を決めています。自由投稿だと投稿の頻度にバラつきが出てしまう可能性もあり、そうなるとブログの見栄えとしてはあまり好ましくありません。編集部がペースメーカーとなって更新頻度を維持することでブログの活気を保つことができると考えています。

「社内のいろんな人に書いてもらいやすい」についてですが、自由投稿の場合ですと、社内で素晴らしい取り組みを行っていたり、目覚ましい成果を上げているけどもブログはあまり書かないという人もいて、機会損失が発生する可能性もあります。編集部体制では、そういった取り組みを行っている人に注目して執筆依頼をしています。先述のように2018年4月以降は約30名のメンバーに執筆してもらうことができ、記事内容もPHPでのWebサービス開発からデザイン思想、データベースや機械学習などバラエティに富んだものになっていると思います。

もちろん、理想はどのメンバーからも「これブログで書きたいんだけど」と次々に提案をもらえ、さまざまな記事が投稿される状態だと思いますし、今回のアドベントカレンダーはまさに理想の形で開催することができ、とても嬉しかったです。

そして記事テイストの統一に関してですが、こちらは編集部でテックブログの執筆マニュアルを用意していたり、公開前に編集部が内容を確認することで実現できているかと思います。とはいえこれは最低限のチェックを行うのみで、執筆者の個性を最大限に活かすよう意識しています。

お祭り感を出す

前述のように、現在は編集部から記事の執筆を依頼する場合があり、依頼の仕方によっては執筆者が義務やタスクのようにネガティブに捉えてしまう可能性もあります。

そこで、記事の公開に関する要所要所でお祭り感を出すことで、執筆を依頼された人もまだ執筆したことのない人も、記事の執筆という行為をポジティブに捉えてもらうことができると考えています。

まず、当たり前ですが記事を公開したらメンバー全員がいるSlackチャンネルでお知らせします。記事を公開したら、Slackの#generalで執筆した人に「こんなの書いたよ」と投稿してもらいます。そうすると代表の鶴岡やCTOの藤川も含め各メンバーがSNSでシェアしてくれるのでちょっとしたお祭り感が出ます。

またはてブのホットエントリ入りした時や、媒体で取り上げられたりしたときにはメンバーが随時共有してくれるので、執筆した本人も嬉しいですよね。

f:id:aiyoneda:20181210110343p:plain

f:id:aiyoneda:20181210110410p:plain

こんな感じでシェアしてくれます。

おわりに

こうやって積極的なテックブログの運営ができるのも、現場のメンバーが日々のプロダクトづくりで様々なことにチャレンジしているからこそです。そして私がこうやって記事がかけるのも編集部のメンバーのサポートのおかげです。この場を借りて記事を執筆してくれるメンバー、編集部のメンバーにはお礼を伝えたいと思います。

今後ともみなさまにお楽しみいただけるようなテックブログの運営をコツコツと続けていきます。

BASEのメンバーは素敵な人たちばかりです。このテックブログを読んでBASEにご興味をもってくださった方は、ぜひ下記をご覧ください!一緒にBASEではたらきましょう!

jobs.binc.jp

明日はBASE株式会社が創業して6周年ということで、代表の鶴岡が記事を書きます!乞うご期待!

SQLアンチパターンとBtreeインデックスの関連性

この記事は、「BASE Advent Calendar 2018」の9日目の記事です。

devblog.thebase.in

前日は id:match_1 でした。こんにちは、10日ほど前にデータベース移行についての記事を書かせていただいた植木です。 今回はインデックスとBtreeのパフォーマンスチューニング系のお話をしたいと思います。

概要

Btreeの構造などを説明している資料は他にもあるし、SQLのアンチパターンもある程度あるけど、何故アンチパターンになるのかなど構造を理解しながらの説明が無いように思っていました。今回はBtreeの構造を説明しながら、どのように動いてパフォーマンスに影響しているのかを説明しようかと思います。SQLのパフォーマンスチューニングはBtreeの構造を理解しているかどうかで全く違うものになります。構造を意識しつつ、誤解しやすいところや何故この処理でインデックスが効くのかなど考えてみましょう。

Btreeの仕組み

Btreeとは

情報処理試験などで出ますから知ってるよって人も多いですよね。ソート処理と木構造によって検索の高速化をするアルゴリズムとなります。このBtree構造がDBのインデックスの内部構造となります。弊社だとMySQL系ですので若干カスタマイズしたB+treeとなります。

下の図を見てほしいのですが、データを格納する単位であるノード内にはインデックス対象のキー値とそれ以外にリーフには実データへのポインタ情報(MySQLだとPK)が入っています。木構造を使った分岐で対象のリーフノードを選択したらポインタ経由で実テーブルにアクセスしてデータを取得します。

f:id:kingyokkun:20181207191659p:plain

B+treeがBtreeと違う点はリーフノードにもブランチノードと同じ情報が入る事とリーフノードに次のリーフのポインタが入る事になります。これらの対応をする事で範囲検索やorder by、group by等の対応がしやすくなります。今回はこのB+treeを使っての説明をいたします。以降、Btreeと書いているものはB+treeです。

今回はわかりやすくしたいのでノード内に1データしか入らないと仮定してキー値に1−10のデータを入れた場合を想定します。実際にはノードに複数レコードが入りますが、ノードの先頭データと末尾データを使って同じような構造と比較をします。

また、参考に普通のBtreeだとこうなります。

f:id:kingyokkun:20181207191718p:plain

何故この構造にデータを並べると早いの?

例えば、今回のように1〜10まであるデータの中で6を探したいと思った場合、通常なら10回6という数字と格納データとを比較する必要があります。ユニーク制約をつける事ができたとしても6回です。それに対して、木構造にしておけば、まずルートノードの5と比較して大きいので右のブランチへ行き、7と比較して小さいので左に行けばもう目当てのデータに辿りつきます。

インデックスをつけない状態なら検索はデータ量に比例した処理時間が必要ですが、木構造にする事で必要な時間はデータ量の対数に比例します。

実際のSQLでよくある問題などなど

範囲検索

下記のような検索をした場合に認識を誤解している方がいます。

where id between 6 and 8

この時、Btree上で6と8の位置を検索してその間のデータを全て取るなんて器用な事はできません。今回の上図データだとおそらくDBが6を選んで検索し、6以降のデータを取得して一つずつ8より小さくないかを比較します。また、その際に6と8どちらかの数字を選択するかを判断するには統計情報を使います。

likeでインデックスが効く場合

ここで少しBtree構造がわかった事だと思うので、前方一致ならlike検索でもインデックスが効く事を説明してみます。例えば、yamada、tanaka、suzuki、yamakawaさんがいた場合にBtreeの構造にしたらsuzuki、tanaka、yamada、yamakawaの順番になりますね。この時に下記のような条件で検索すればyamadaさんの直前の位置まで木構造の動きで辿りつく事ができ、それ以降のデータを取得する動きができるという事になります。「%yama%」のような中間一致や後方一致では、Btreeのソート順が活かせないためBtree検索はできません。

where name like 'yama%'

検索キーに関数や演算を使うとインデックスが効かない

Btreeはデータをソートしている事が重要な訳ですが、例えば、下記のように関数を使った場合、ソート順が変わる可能性があります。

where date(update_time)='2018-01-01'

もっとわかりやすくreverse関数を使えばソート順は真逆になります。一つ一つの関数や演算の特徴までDBは把握しきれないためインデックスを利用できません。

複合インデックスの構造

続いて複合インデックスの場合のBtree構造です。購入などの情報をイメージしてもらえると良いかと思います。今回はユーザーと購入日をイメージしてみます。(user_id,update_dt)にインデックスをつけてuser_idが0001〜0004の人が1/1から1/3まで何らかの操作をした場合、インデックス内部のBtreeはこのような並びになります。

f:id:kingyokkun:20181207191808p:plain

ここで下記のように検索すれば木構造の動きで(0003,2018-01-02)まで到達します(黄色塗り)。

where user_id='0003' and update_dt>='2018-01-02'

後はそれ以降の第一キーが0003のリーフを取得すればいいわけです。(本当はINSERT順考えたらこの木構造にはならないけど、今回は気にしない)

f:id:kingyokkun:20181207191834p:plain

複合インデックスの順番誤り

日付とキーの順番を逆にしている場合がよくあります。(update_dt,userid)でインデックスをつけているわけです。そうなるとこういった構造になります。

f:id:kingyokkun:20181207192007p:plain

この状態で先ほどと同じく「user_id='0003' and update_dt>='2018-01-02'」を検索しても、第一キーであるupdate_dtが'2018-01-02'の先頭(黄色塗り)を検索して、それ以降の8つのデータを全て取得し、user_idが0003と同じかを比較するという処理になります。このようにキーの順番を間違えると非効率な処理となります。

f:id:kingyokkun:20181207192029p:plain

キー飛ばし

ソート順が重要なので、基本的に第一キーを飛ばして第二キーのみを指定したクエリを実行してもインデックスは機能しません。第三キーまであるインデックスを作ってwhere句で第二キーを指定しない場合は第一キーまでのソート順が利用できるため第一キーだけのインデックスと同じ動きとなります。

最適な複合インデックスの順番づけ

そんなものはありません。まず、=で検索するキーを上位に置きます。続いて上で書いたような範囲検索で使うキー(よくあるのが日付)やinで取得するようなキーを指定します。必須であればあるほど上位のキーにする事が重要です。そして範囲検索やINでの検索はそれによってどれだけ絞り込みができるかが重要なのでアプリケーション仕様にまで踏み込まないとなかなか判断は難しいです。

アプリケーション仕様によって、キーが指定される場合とされない場合などがありますので、そういう場合は(key1,key2,key3)のインデックス以外に(key1,key3)のキーも作るなどアプリケーションが指定するキーと実行頻度を考えて最適なインデックス構成を考える必要があります。

最後に

Btreeの構造を理解すればわかるSQLパフォーマンスに関わる事をいくつかあげてみました。パフォーマンスチューニングにはジョインアルゴリズムの理解なども大きく響くのですが、まずはBtreeの理解をするのが一番だと思います。むしろ、ここを理解していないと確信を持ってのチューニングはできません。内部構造を理解して説明できる方が増えればSQL、DBのパフォーマンスもよくなりますので、是非ご理解いただけると良いかと思います。

BASEのSREチームではお客様に安心して買い物をしていただくために、サービスの安定性に責任を持ち、インフラ・アーキテクチャの改善に日々取り組み続けております。 ご興味を持たれた方いらっしゃいましたら是非ご連絡いただければ幸いです。 https://jobs.binc.jp/